Flutter流媒体处理插件stream24的使用
Flutter流媒体处理插件stream24的使用
安装
要将stream24
插件添加到你的项目中,请在项目的pubspec.yaml
文件中添加以下依赖:
dependencies:
...
stream24: ^0.1.1
...
然后运行flutter pub get
来获取新添加的依赖。
使用
Stream24RichPage
Stream24RichPage
是一个具有丰富HTML内容并自动调整高度的webview小部件。以下是其参数列表及其描述:
参数名 | 类型 | 描述 |
---|---|---|
brand |
string |
品牌名称,必须填写。 |
productId |
string |
产品ID,必须填写。 |
retailerDomain |
string |
零售商域名,必须填写。 |
templateType |
string |
页面模板类型,必须填写。 |
language |
string |
语言编码,格式为国家_语言。默认值为ru_ru 。 |
onError |
Function(String) |
当发生错误时调用的函数。 |
resultType |
Stream24ResultType |
页面结果类型。可以是.json , .html 或.iframe 。默认值为.html 。 |
contentType |
Stream24ContentType |
页面内容类型。可以是.shopInShops 或.minisite 。默认值为.minisite 。 |
示例代码
import 'package:flutter/material.dart';
import 'package:stream24/stream24.dart';
import 'package:stream24/rich_page.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewPage extends StatefulWidget {
WebViewPage({super.key});
[@override](/user/override)
State<WebViewPage> createState() => _WebViewPageState();
}
class _WebViewPageState extends State<WebViewPage> {
[@override](/user/override)
Widget build(BuildContext context) {
return Stream24RichPage(
brand: 'Samsung',
productId: '16651081549',
retailerDomain: 'irshad.az',
templateType: 'master_template',
contentType: Stream24ContentType.shopInShops,
onError: (errorMsg) {
print(errorMsg);
}
);
}
}
getHtml
getHtml
方法返回页面的HTML代码作为字符串。以下是其参数列表及其描述:
参数名 | 类型 | 描述 |
---|---|---|
brand |
string |
品牌名称,必须填写。 |
productId |
string |
产品ID,必须填写。 |
retailerDomain |
string |
零售商域名,必须填写。 |
templateType |
string |
页面模板类型,必须填写。 |
language |
string |
语言编码,格式为国家_语言。默认值为ru_ru 。 |
contentType |
Stream24ContentType |
页面内容类型。可以是.shopInShops 或.minisite 。默认值为.minisite 。 |
示例代码
import 'package:flutter/material.dart';
import 'package:stream24/stream24.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewPage extends StatefulWidget {
WebViewPage({super.key});
[@override](/user/override)
State<WebViewPage> createState() => _WebViewPageState();
}
class _WebViewPageState extends State<WebViewPage> {
late WebViewController controller;
double height = 120;
[@override](/user/override)
void initState() {
super.initState();
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel("FlutterWebviewHeight", onMessageReceived: (JavaScriptMessage msg) {
setState(() {
height = double.tryParse(msg.message) ?? 0;
});
})
..loadHtmlString(Stream24.getHtml(
brand: 'Samsung',
productId: '16651081549',
retailerDomain: 'irshad.az',
templateType: 'master_template',
contentType: Stream24ContentType.shopInShops,
));
}
[@override](/user/override)
Widget build(BuildContext context) {
return SizedBox(
height: height,
child: WebViewWidget(
controller: controller,
),
);
}
}
检查内容可用性
你可以通过checkContentAvailability
方法检查是否可以通过给定的参数获取到富页面内容。以下是其参数列表及其描述:
参数名 | 类型 | 描述 |
---|---|---|
brand |
string |
品牌名称,必须填写。 |
productId |
string |
产品ID,必须填写。 |
retailerDomain |
string |
零售商域名,必须填写。 |
templateType |
string |
页面模板类型,必须填写。 |
language |
string |
语言编码,格式为国家_语言。默认值为ru_ru 。 |
contentType |
Stream24ContentType |
页面内容类型。可以是.shopInShops 或.minisite 。默认值为.minisite 。 |
completion |
Function(bool) |
当结果返回时触发的函数,输入布尔值表示内容是否可用。 |
示例代码
import 'package:stream24/stream24.dart';
Stream24.checkContentAvailability(
brand: 'TestBrand',
retailerDomain: '24ttl.ru',
productId: '920-969696',
templateType: 'master_template',
language: 'ru',
contentType: Stream24ContentType.minisite,
completion: (available) {
print("Content is ${available ? "available" : "unavailable"}");
}
);
示例
下面是一个完整的示例代码,展示了如何使用stream24
插件创建一个包含表单的页面,允许用户输入参数并显示富页面内容。
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:stream24/stream24.dart';
import 'package:stream24_example/webview_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
super.key,
});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late TextEditingController retailerDomainController,
brandController,
productIdController,
templateTypeController,
languageController,
pageController;
bool throwError = true;
Stream24ContentType contentType = Stream24ContentType.shopInShops;
Stream24ResultType resultType = Stream24ResultType.html;
List<RichPageTemplate> _templates = [];
[@override](/user/override)
void initState() {
super.initState();
retailerDomainController = TextEditingController(text: 'irshad.az');
brandController = TextEditingController(text: 'Samsung');
productIdController = TextEditingController(text: '16651081549');
templateTypeController = TextEditingController(text: 'master_template');
pageController = TextEditingController(text: 'index.html');
languageController = TextEditingController(text: 'ru');
_fetchSavedTemplates();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
physics: ClampingScrollPhysics(),
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
decoration: const InputDecoration(labelText: "Retailer domain"),
controller: retailerDomainController,
),
TextField(
decoration: const InputDecoration(labelText: "Brand"),
controller: brandController,
),
TextField(
decoration: const InputDecoration(labelText: "Product ID"),
controller: productIdController,
),
TextField(
decoration: const InputDecoration(labelText: "Language"),
controller: languageController,
),
TextField(
decoration: const InputDecoration(labelText: "Template type"),
controller: templateTypeController,
),
DropdownButton<bool>(
value: throwError,
items: const [
DropdownMenuItem(
value: true,
child: Text('Throw error'),
),
DropdownMenuItem(
value: false,
child: Text('Don\'t throw error'),
),
],
onChanged: (_throwError) {
setState(() {
throwError = _throwError!;
});
},
),
DropdownButton<Stream24ContentType>(
value: contentType,
items: const [
DropdownMenuItem(
value: Stream24ContentType.shopInShops,
child: Text('Shop in shops'),
),
DropdownMenuItem(
value: Stream24ContentType.minisite,
child: Text('Minisite'),
),
],
onChanged: (type) {
setState(() {
contentType = type!;
});
},
),
DropdownButton<Stream24ResultType>(
value: resultType,
items: const [
DropdownMenuItem(
value: Stream24ResultType.html,
child: Text('html'),
),
DropdownMenuItem(
value: Stream24ResultType.json,
child: Text('json'),
),
DropdownMenuItem(
value: Stream24ResultType.iframe,
child: Text('iframe'),
),
],
onChanged: (type) {
setState(() {
resultType = type!;
});
},
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Flexible(
child: TextButton(
onPressed: () async {
saveTemplate(RichPageTemplate(
brand: brandController.value.text,
retailerDomain: retailerDomainController.value.text,
productId: productIdController.value.text,
templateType: templateTypeController.value.text,
language: languageController.value.text,
page: pageController.value.text,
throwError: throwError,
contentType: contentType,
resultType: resultType,
));
},
child: Row(
children: [
Icon(Icons.save_rounded),
const Text("Save template"),
],
),
style: ButtonStyle(foregroundColor: MaterialStatePropertyAll<Color>(Colors.green)),
),
),
Flexible(
child: TextButton(
onPressed: () async {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => WebViewPage(
brand: brandController.value.text,
productId: productIdController.value.text,
retailerDomain: retailerDomainController.value.text,
templateType: templateTypeController.value.text,
language: languageController.value.text,
contentType: contentType,
),
),
);
},
child: const Text("Open page"),
style: ButtonStyle(foregroundColor: MaterialStatePropertyAll<Color>(Colors.blue)),
),
),
],
),
Divider(),
Text(
'Saved templates:',
style: Theme.of(context).textTheme.titleMedium,
),
Column(
children: _templates.reversed.map((element) {
return Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 5)],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(element.brand),
Text(element.retailerDomain),
Text(element.productId),
Text(element.language),
Text(element.templateType),
Text(element.throwError ? 'Throw error' : "Don't throw error"),
Text(element.contentType.toString().replaceFirst('.', ': ')),
Text(element.resultType.toString().replaceFirst('.', ': ')),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
onPressed: () async {
removeTemplate(element);
},
child: Row(
children: [
Icon(Icons.delete_forever),
const Text("Remove"),
],
),
style: ButtonStyle(foregroundColor: MaterialStatePropertyAll<Color>(Colors.red)),
),
TextButton(
onPressed: () async {
useTemplate(element);
},
child: Row(
children: [
Icon(Icons.check),
const Text("Apply"),
],
),
style: ButtonStyle(foregroundColor: MaterialStatePropertyAll<Color>(Colors.blue)),
),
],
),
],
),
);
}).toList(),
),
],
),
),
),
);
}
saveTemplate(RichPageTemplate newTemplate) {
if (_templates.contains(newTemplate)) {
return;
}
_templates.add(newTemplate);
setState(() {});
saveTemplates();
}
Future saveTemplates() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setStringList(
'templates',
_templates.map((e) => e.toJson()).toList(),
);
}
Future _fetchSavedTemplates() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
var jsonsList = prefs.containsKey('templates') ? prefs.getStringList('templates')! : [];
for (var jsonString in jsonsList) {
_templates.add(RichPageTemplate.fromJson(jsonString));
}
setState(() {});
}
void useTemplate(RichPageTemplate element) {
setState(() {
retailerDomainController.text = element.retailerDomain;
brandController.text = element.brand;
productIdController.text = element.productId;
templateTypeController.text = element.templateType;
pageController.text = element.page;
languageController.text = element.language;
throwError = element.throwError;
contentType = element.contentType;
resultType = element.resultType;
});
}
void removeTemplate(RichPageTemplate element) {
if (_templates.remove(element)) {
setState(() {});
saveTemplates();
}
}
}
class RichPageTemplate {
String retailerDomain, brand, productId, templateType, language, page;
bool throwError;
Stream24ContentType contentType;
Stream24ResultType resultType;
RichPageTemplate({
required this.brand,
required this.retailerDomain,
required this.productId,
required this.templateType,
required this.language,
required this.page,
required this.throwError,
required this.contentType,
required this.resultType,
});
factory RichPageTemplate.fromJson(String jsonMap) {
Map<String, dynamic> map = json.decode(jsonMap) as Map<String, dynamic>;
return RichPageTemplate(
brand: map['brand']!,
retailerDomain: map['retailerDomain']!,
productId: map['productId']!,
templateType: map['templateType']!,
language: map['language']!,
page: map['page']!,
throwError: map['throwError']! == 'true',
contentType: _contentTypeMap[map['contentType']!]!,
resultType: _resultTypeMap[map['resultType']!]!,
);
}
static String _getContentType(Stream24ContentType contentType) {
switch (contentType) {
case Stream24ContentType.shopInShops:
return 'sis';
case Stream24ContentType.minisite:
return 'minisite';
}
}
static String _getResultType(Stream24ResultType resultType) {
switch (resultType) {
case Stream24ResultType.json:
return 'json';
case Stream24ResultType.html:
return 'html';
case Stream24ResultType.iframe:
return 'iframe';
}
}
static final Map<String, Stream24ContentType> _contentTypeMap = {
'sis': Stream24ContentType.shopInShops,
'minisite': Stream24ContentType.minisite,
};
static final Map<String, Stream24ResultType> _resultTypeMap = {
'json': Stream24ResultType.json,
'html': Stream24ResultType.html,
'iframe': Stream24ResultType.iframe,
};
String toJson() {
return json.encode({
"brand": brand,
"retailerDomain": retailerDomain,
"productId": productId,
"templateType": templateType,
"language": language,
"page": page,
"throwError": throwError.toString(),
"contentType": _getContentType(contentType),
"resultType": _getResultType(resultType),
});
}
[@override](/user/override)
bool operator ==(Object other) {
if (other is! RichPageTemplate) return false;
if (other.hashCode != hashCode) return false;
if (brand != other.brand) return false;
if (retailerDomain != other.retailerDomain) return false;
if (productId != other.productId) return false;
if (language != other.language) return false;
if (templateType != other.templateType) return false;
if (page != other.page) return false;
if (throwError != other.throwError) return false;
if (contentType != other.contentType) return false;
if (resultType != other.resultType) return false;
return true;
}
[@override](/user/override)
int get hashCode {
var result = 1;
result *= brand.hashCode * retailerDomain.hashCode * productId.hashCode * language.hashCode * templateType.hashCode * page.hashCode * throwError.hashCode * contentType.hashCode * resultType.hashCode;
return result;
}
}
更多关于Flutter流媒体处理插件stream24的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter流媒体处理插件stream24的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用stream24
插件进行流媒体处理的示例代码。stream24
是一个假设的Flutter插件名称,用于演示目的。实际使用中,你需要根据具体的插件文档和API进行调整。
首先,确保你已经在pubspec.yaml
文件中添加了stream24
插件的依赖:
dependencies:
flutter:
sdk: flutter
stream24: ^x.y.z # 替换为实际版本号
然后运行flutter pub get
来安装依赖。
接下来,我们将展示如何在Flutter应用中使用这个插件进行流媒体处理。以下是一个简单的示例代码:
import 'package:flutter/material.dart';
import 'package:stream24/stream24.dart'; // 假设这是插件的导入路径
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Stream24 Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Stream24DemoPage(),
);
}
}
class Stream24DemoPage extends StatefulWidget {
@override
_Stream24DemoPageState createState() => _Stream24DemoPageState();
}
class _Stream24DemoPageState extends State<Stream24DemoPage> {
Stream24Client? _stream24Client;
String _streamStatus = "Not Connected";
@override
void initState() {
super.initState();
_initializeStream24Client();
}
void _initializeStream24Client() async {
// 假设Stream24Client是插件提供的主要类
_stream24Client = Stream24Client(
apiKey: "your_api_key_here", // 替换为你的API密钥
onStreamStatusChanged: (status) {
setState(() {
_streamStatus = status;
});
},
onError: (error) {
print("Stream24 Error: $error");
},
);
// 连接到流媒体服务器(假设的方法)
await _stream24Client!.connectToServer("your_stream_url_here");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stream24 Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Stream Status: $_streamStatus',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
if (_stream24Client!.isConnected) {
await _stream24Client!.disconnectFromServer();
} else {
await _stream24Client!.connectToServer("your_stream_url_here");
}
setState(() {
// 更新按钮文本或状态
});
},
child: Text(_stream24Client?.isConnected ?? false
? 'Disconnect'
: 'Connect'),
),
],
),
),
);
}
@override
void dispose() {
_stream24Client?.dispose();
super.dispose();
}
}
// 假设的Stream24Client类定义(在实际使用中,这个类将由插件提供)
class Stream24Client {
String apiKey;
Function(String) onStreamStatusChanged;
Function(dynamic) onError;
bool? _isConnected;
Stream24Client({
required this.apiKey,
required this.onStreamStatusChanged,
required this.onError,
}) {
_isConnected = false;
}
bool get isConnected => _isConnected ?? false;
Future<void> connectToServer(String url) async {
// 模拟连接过程
await Future.delayed(Duration(seconds: 2));
_isConnected = true;
onStreamStatusChanged("Connected");
}
Future<void> disconnectFromServer() async {
// 模拟断开连接过程
await Future.delayed(Duration(seconds: 1));
_isConnected = false;
onStreamStatusChanged("Disconnected");
}
void dispose() {
// 清理资源
}
}
请注意,上述代码中的Stream24Client
类是一个假设的类,用于模拟插件可能提供的API。在实际使用中,你需要根据stream24
插件的实际文档和API来实现相应的功能。
另外,确保在实际应用中处理错误和异常情况,并根据需要添加更多的功能和UI元素。