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

1 回复

更多关于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元素。

回到顶部