lexo_ttplayer_decryption 1.1.2 copy "lexo_ttplayer_decryption: ^1.1.2" to clipboard
lexo_ttplayer_decryption: ^1.1.2 copied to clipboard

This plugin is developed based on the Flutter plugin of Volcano VOD SDK, supports video decryption

example/lib/main.dart

// ignore_for_file: prefer_const_constructors, unused_import

import 'dart:io';
import 'dart:ui';
import 'dart:convert';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:path_provider/path_provider.dart';
import 'package:lexo_ttplayer_decryption/ve_vod.dart';
import 'package:vod_player_flutter_example/component/generic_text_button_item.dart';
import 'package:vod_player_flutter_example/global_configuration.dart';
import 'package:vod_player_flutter_example/home/play_setting_page.dart';
import 'package:vod_player_flutter_example/platform_keys.dart';
import 'package:vod_player_flutter_example/short_video_play_scene.dart';
import 'package:vod_player_flutter_example/short_video/short_video_feed_item.dart';
import 'package:vod_player_flutter_example/short_video/short_video_feed_util.dart';
import 'package:vod_player_flutter_example/test_entry/test_entry.dart';
import 'package:vod_player_flutter_example/video_preload.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:vod_player_flutter_example/long_video/long_video_page.dart';
import 'package:vod_player_flutter_example/mini_drama/mini_drama_scene.dart';
import 'package:vod_player_flutter_example/utils/network_utils.dart';

void main() async {
  if (Platform.isAndroid) {
    WidgetsFlutterBinding.ensureInitialized();
  }

  runApp(const MyApp());
  DartPluginRegistrant.ensureInitialized();
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<ShortVideoFeedItem>? shortVideofeedlist;
  List<dynamic>? miniDramaEpisodes;
  final String _appID = '229234';

  @override
  void initState() {
    super.initState();

    initPlatformState();

    Connectivity()
        .onConnectivityChanged
        .listen((List<ConnectivityResult> result) async {
      if (result.contains(ConnectivityResult.none)) {
        Fluttertoast.showToast(
            msg: "网络连接失败,请稍后重试", gravity: ToastGravity.CENTER);
      } else {
        Fluttertoast.showToast(
            msg: "网络恢复,重新获取Feed", gravity: ToastGravity.CENTER);
        // 确保配置已加载后再获取数据
        await GlobalConfiguration.initSharedPreferences();
        fetchShortVideoFeed();
        fetchMiniDramaEpisodes();
      }
      // Received changes in available connectivity types!
    });
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    await GlobalConfiguration.initSharedPreferences();
    // Detect byteplus flag from compile-time environment variable
    const String? byteplusEnable = String.fromEnvironment('BYTEPLUS_ENABLE');
    if (byteplusEnable == 'true') {
      GlobalConfiguration.isByteplusEnable = true;
    }
    // open log module
    await FlutterTTSDKManager.openAllLog();
    // regist log callback
    TTFLogger.onLog = (logLevel, msg) {
      print(msg);
    };

    // download
    TTVideoEngineDownloadTaskManager.enableHlsProxy(true);
    String docDir;
    if (Platform.isIOS) {
      docDir = (await getApplicationDocumentsDirectory()).path;
    } else {
      docDir = (await getDownloadsDirectory())!.path;
    }
    docDir = "$docDir/vevod_download";
    TTVideoEngineDownloadTaskManager.setDownloadDirectory(docDir);

    // setup
    String licPath = 'assets/VEVod.license';
    // please replace it with current channel, example "App Store" for iOS
    String channel = Platform.isAndroid ? 'demo_channel_android' : 'App Store';
    TTSDKVodConfiguration vodConfig = TTSDKVodConfiguration();
    vodConfig.cacheMaxSize = 300 * 1024 * 1024;
    TTSDKConfiguration sdkConfig =
        TTSDKConfiguration.defaultConfigurationWithAppIDAndLicPath(
            appID: _appID, licenseFilePath: licPath, channel: channel);
    sdkConfig.vodConfiguration = vodConfig;
    sdkConfig.appName = "bytevod_flutter_demo";
    sdkConfig.appVersion = "1.1.1";
    // sdkConfig.appRegion =
    //     TTSDKServiceVendor.TTSDKServiceVendorMYA; // 接入海外地域必填;不填写默认华北
    await FlutterTTSDKManager.startWithConfiguration(sdkConfig);
    // init startup auto select strategy

    if (GlobalConfiguration.enableStartupAutoSelectBitrate) {
      await FlutterTTSDKManager.initStartupAutoSelectStrategy();
    }
    // deviceID
    FlutterTTSDKManager.setCurrentUserUniqueID('test_1234');
    String? uniqueID = await FlutterTTSDKManager.getCurrentUserUniqueID();
    String? deviceID = await FlutterTTSDKManager.getDeviceID();
    String? engineUniqueId = await FlutterTTSDKManager.getEngineUniqueId();
    print(
        "TTF -- uniqueId:$uniqueID deviceId:$deviceID engineUniqueId:$engineUniqueId");

    // strategy
    updateStrategy();

    // download
    updateDownloader();

    if (!mounted) return;
    setState(() {});
  }

  Future<void> updateDownloader() async {
    TTVideoEngineDownloadTaskManager.setMaxDownloadOperationCount(3); // 最大并发下载数
    TTVideoEngineDownloadTaskManager.setLimitFreeDiskSize(
        1024 * 1024 * 1024); // 空闲磁盘空间大小
    TTVideoEngineDownloadTaskManager.setLimitFreeDiskCount(500); // 空闲磁盘空间文件数
    TTVideoEngineDownloadTaskManager.loadAllTask();
  }

  Future<void> updateStrategy() async {
    if (GlobalConfiguration.enableStrategyPreload &&
        GlobalConfiguration.enableStrategyPreRender) {
      TTVideoEngineStrategy.enableEngineStrategy(
          strategyType: TTVideoEngineStrategyType.preloadAndPreRender,
          scene: TTVideoEngineStrategyScene.smallVideo);
      _enableEnginePreRenderStrategy(true);
    } else if (GlobalConfiguration.enableStrategyPreload) {
      TTVideoEngineStrategy.enableEngineStrategy(
          strategyType: TTVideoEngineStrategyType.preload,
          scene: TTVideoEngineStrategyScene.smallVideo);
    } else if (GlobalConfiguration.enableStrategyPreRender) {
      TTVideoEngineStrategy.enableEngineStrategy(
          strategyType: TTVideoEngineStrategyType.preRender,
          scene: TTVideoEngineStrategyScene.smallVideo);
      _enableEnginePreRenderStrategy(true);
    } else {
      TTVideoEngineStrategy.clearAllEngineStrategy();
    }
  }

  Future<void> fetchShortVideoFeed() async {
    if (shortVideofeedlist != null) {
      return;
    }
    ShortVideoFeedUtil.requestFeed((List<ShortVideoFeedItem>? feedlist) {
      if (feedlist != null) {
        setState(() {
          shortVideofeedlist = feedlist;
          Fluttertoast.showToast(
              msg: "获取小视频数据成功", gravity: ToastGravity.CENTER);
        });
      } else {
        Fluttertoast.showToast(
            msg: "获取数据异常,请退出重试", gravity: ToastGravity.CENTER);
      }
    });
  }

  Future<void> fetchMiniDramaEpisodes() async {
    if (miniDramaEpisodes != null) {
      return;
    }
    final bool useVidSource = GlobalConfiguration.miniDramaVideoSourceType == 0;
    final String apiUrl = useVidSource
        ? 'https://vevod-demo-server.volcvod.com/api/drama/episode/v1/getEpisodeFeedStreamWithPlayAuthToken'
        : 'https://vevod-demo-server.volcvod.com/api/drama/episode/v1/getDramaEpisodeWithVideoModel';

    final episodes = await NetworkUtils.postRequestForResult(
      apiUrl,
      {
        'authorId': 'mini-drama-video',
        'needSsl': true,
        'dramaId': '3',
        'offset': 0,
        'pageSize': 50,
        'format': GlobalConfiguration.miniDramaVideoFormat,
      },
      errorMessage: '获取短剧数据失败',
    );

    if (episodes != null) {
      Fluttertoast.showToast(msg: "获取短剧数据成功", gravity: ToastGravity.CENTER);
      setState(() {
        miniDramaEpisodes = episodes;
      });
    }
  }

  Future<void> _enableEnginePreRenderStrategy(bool enable) async {
    if (enable) {
      TTVideoEngineStrategy.init();

      TTVideoEngineStrategy.onCreatePreRenderEngine = ((source) async {
        VodPlayerFlutter player = VodPlayerFlutter();
        String coreHashHex =
            await player.createPlayer(vid: source.getVid, preCreated: true);
        player.setMediaSource(source);
        player.setHardwareDecode(GlobalConfiguration.isHardwareDecode);
        player.setTrackVolumeEnabled(GlobalConfiguration.isTrackVolume);
        player.setScalingMode(
            TTVideoEngineScalingMode.TTVideoEngineScalingModeAspectFit);
        player.openTextureRender(!GlobalConfiguration.closeTextureRender);
        player.setLooping(true);
        player.setCustomHeader('x-tt-flutter-test-demo', '1');
        print(
            'TTF -- TTVideoEngineStrategyPreRender onCreatePreRenderEngine, hashCode:${player.hashCode} engine:$coreHashHex vid:${source.getVid}');
        return player;
      });

      TTVideoEngineStrategy.onPlayerCreated = ((player) {
        if (player != null) {
          print('TTF ---o onPlayerCreated, hashCode ' +
              player.hashCode.toString());
        }
      });

      print('TTF -- TTVideoEngineStrategyPreRender - init end');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Builder(
      builder: (context) => Scaffold(
        backgroundColor: const Color.fromRGBO(244, 245, 247, 1),
        body: ListView(
          padding: EdgeInsets.zero,
          children: [
            Container(
              height: 280,
              color: Colors.transparent,
              child: Stack(
                children: [
                  Image.asset(
                    'assets/images/icon_home_background.png',
                  ),
                  const Positioned(
                    top: 180,
                    left: 30,
                    child: Text('视频点播',
                        style: TextStyle(
                            color: Colors.black,
                            fontSize: 24,
                            fontWeight: FontWeight.bold)),
                  ),
                  const Positioned(
                    top: 220,
                    left: 30,
                    child: Text('体验一站式视频解决方案',
                        style: TextStyle(color: Colors.black, fontSize: 16)),
                  ),
                ],
              ),
            ),
            GenericTextButtonItem(
                iconAssetPath: 'assets/images/icon_short.png',
                buttonText: '小视频(竖屏类抖音)',
                onPressed: () {
                  if (shortVideofeedlist == null) {
                    Fluttertoast.showToast(msg: "暂无数据 请稍后重试");
                  } else {
                    if (_appID.isEmpty) {
                      Fluttertoast.showToast(
                          msg:
                              "Please contact Volcano Engine Business to get the demo AppId and License.",
                          gravity: ToastGravity.CENTER);
                      return;
                    }
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => ShortVideoScene(
                          feedlist: shortVideofeedlist!,
                        ),
                      ),
                    );
                  }
                }),
            SizedBox(height: 10),
            GenericTextButtonItem(
                iconAssetPath: 'assets/images/icon_short.png',
                buttonText: '短剧',
                onPressed: () {
                  if (miniDramaEpisodes == null) {
                    Fluttertoast.showToast(
                        msg: '暂无数据 请稍后重试', gravity: ToastGravity.CENTER);
                  } else {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => MiniDramaScene(
                          initialEpisodesJson: miniDramaEpisodes,
                        ),
                      ),
                    );
                  }
                }),
            SizedBox(height: 10),
            GenericTextButtonItem(
                iconAssetPath: 'assets/images/icon_test.png',
                buttonText: '长视频',
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const LongVideoPage(),
                    ),
                  );
                }),
            SizedBox(height: 10),
            GenericTextButtonItem(
                iconAssetPath: 'assets/images/icon_test.png',
                buttonText: '测试',
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const TestPage(),
                    ),
                  );
                }),
            SizedBox(height: 10),
            GenericTextButtonItem(
                iconAssetPath: 'assets/images/icon_setting.png',
                buttonText: '播放设置',
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const PlaySettingPage(),
                    ),
                  );
                }),
            SizedBox(height: 20),
            Container(
              height: 75,
              margin: const EdgeInsets.symmetric(horizontal: 10),
              alignment: Alignment.center,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: const [
                  Text(
                      'byteplus_vod version: ${FlutterTTSDKManager.TTSDK_FLUTTER_VERSION}',
                      style: TextStyle(
                          color: Color.fromRGBO(170, 170, 170, 1),
                          fontSize: 14,
                          fontWeight: FontWeight.w300)),
                  Text('BytePlus Pte Ltd.',
                      style: TextStyle(
                          color: Color.fromRGBO(170, 170, 170, 1),
                          fontSize: 14,
                          fontWeight: FontWeight.w300)),
                ],
              ),
            )
          ],
        ),
      ),
    ));
  }
}
0
likes
140
points
301
downloads

Publisher

unverified uploader

Weekly Downloads

This plugin is developed based on the Flutter plugin of Volcano VOD SDK, supports video decryption

Homepage

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on lexo_ttplayer_decryption

Packages that implement lexo_ttplayer_decryption