Flutter 3.0+ 利用VLC播放器使用rtsp协议,本地测试和打包压缩

发布时间 2023-07-31 11:08:03作者: 一瓶没有脾气的汽水

Flutter 中使用 rtsp 协议

在 Flutter 中可以集成 VLC 播放器通过 rtsp 协议连接到监控相机来实现远程监控,当然也可以用来做直播 APP。

使用 flutter_vlc_player 库

扩展包地址点我跳转

首先在 pubspec.yaml 中添加库引用:

dependencies:
  flutter_vlc_player: ^7.2.0

安卓端配置

  1. android/app/src/main/AndroidManifest.xml中添加网络使用权限

<uses-permission android:name="android.permission.INTERNET" />

  1. 如果 rtsp 为非加密连接,则需要加上明文网络使用权限

android:usesClearTextTraffic="true"

  1. android/app/build.gradle中加入以下配置:
    android {
        packagingOptions {
        // Fixes duplicate libraries build issue,
        // when your project uses more than one plugin that depend on C++ libs.
            pickFirst 'lib/**/libc++_shared.so'
        }

    buildTypes {
        release {
            minifyEnabled true
            useProguard true
            proguardFiles getDefaultProguardFile(
                    'proguard-android-optimize.txt'),
                    'proguard-rules.pro'
        }
    }
    }

请注意,如果您的 gradle 版本较新,那么 useProguard 已经不再使用,请删除这一行。

  1. android/app目录内新建一个proguard-rules.pro文件,内容为

-keep class org.videolan.libvlc.** { *; }

  1. 调整android/app/build.gradle中的 minSdkVersion。
    defaultConfig {
        minSdkVersion 27  //20以上
        targetSdkVersion flutter.targetSdkVersion
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

使用 flutter_vlc_player 库

import 'package:flutter/material.dart';
import 'package:flutter_vlc_player/flutter_vlc_player.dart';

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

  @override
  State<VLCTest> createState() => _VLCTestState();
}

class _VLCTestState extends State<VLCTest> {
  late VlcPlayerController _vlcPlayerController;
  String host = "rtsp://192.168.2.22:8554/mystream";

  @override
  void initState() {
    super.initState();
    _vlcPlayerController = VlcPlayerController.network(
        host,
        hwAcc: HwAcc.full,
        autoPlay: true);
  }

  @override
  void dispose() async {
    // TODO: implement dispose
    super.dispose();
    await _vlcPlayerController.stopRendererScanning();
    await _vlcPlayerController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FractionallySizedBox(
      widthFactor: 1,
      heightFactor: 1,
      child: Center(
        child: VlcPlayer(controller: _vlcPlayerController, aspectRatio: 16 / 9),
      ),
    );
  }
}

本地测试

下面就是本地测试环节,需要在本地建立 rtsp 服务器并推流,在 flutter 程序中连接并拉取。

使用 OBS+OBS-RTSPServer 插件搭建 rtsp 服务器并将桌面推流

目前(截止 2023 年 7 月)OBS-RTSPServer 插件最新 release 版本为 3.0,支持的最新 OBS 版本为 28,

OSB下载 28.x 版本安装 OBS 本体。

然后在obs-rtspserver v3.0.0下载 3.0.0 版本插件安装

全部安装完成后,在 OBS 中新建场景-桌面。

在工具-RTSP 服务器中设置“目标”中的 URL 为rtsp://localhost:8554/mystream,然后打开服务器即可。

注意,不需要设置 OBS 的推流功能,现在就已经在 rtsp 服务器中推流了。

使用 flutter 进行测试

将 flutter 代码中的 host 地址改为rtsp://localhost:8554/mystream,打开这个界面稍等一会儿就会自动播放。

如果 flutter 中无法播放,请下载一个 VLC 播放器或 potplayer 播放上述地址进行测试。

延迟优化

经过上述步骤的测试,我们发现有延迟问题,推流端的延迟我们无法保证,因为往往推流的是监控设备。

于是我们先优化拉取的延迟问题。

我们可以将 VLC 的拉流缓存时长调低就可以极大缓解延迟问题。

_vlcPlayerController = VlcPlayerController.network(
        host,
        hwAcc: HwAcc.full,
        autoPlay: true,
        options: VlcPlayerOptions(
            advanced: VlcAdvancedOptions([
          VlcAdvancedOptions.liveCaching(100),
          VlcAdvancedOptions.networkCaching(100)
        ])));

当然如果您有更好的优化方案,烦请告知,感谢!

打包压缩

通过flutter build apk后,我们发现安装包竟增加了 100+MB!这是不可接收的!

使用flutter build apk --analyze-size 分析我们发现在打包过程中 flutter 自动将所有 abi 打包进了 APK 包里。

于是我们可以用flutter build apk --release --split-per-abi --target-platform android-arm,android-arm64来指定目标平台。

针对打包后体积过大的问题,有人如下说道

VLC uses lots of native code. As a result, it has 18-30MB of native libraries per CPU architecture. While that will be compressed somewhat in the APK, a 57MB increase in APK is actually better than I would expect.

You either need to:

  • Live with it, or

  • Use splits or product flavors to indicate which subset of CPU architectures you are willing to support (the library itself supports arm64-v8a, armeabi-v7a, mips, x86, and x86_64), or

  • Do not use VLC