flutter拉流

517 阅读2分钟

1,引入vlc

flutter_vlc_player: 

2,代码

import 'package:flutter/material.dart';


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

class LivestreamPlayer extends StatefulWidget {

  @override
  LivestreamPlayerState createState() => LivestreamPlayerState();
}

class LivestreamPlayerState extends State<LivestreamPlayer>
    with AutomaticKeepAliveClientMixin , WidgetsBindingObserver {
  late VlcPlayerController _controller;

  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    super.initState();
    //initialize the player with downstreamUrl
    _controller = VlcPlayerController.network("rtmp://:/live/stream",
        options: VlcPlayerOptions());
    WidgetsBinding.instance?.addObserver(this);
  }

  @override
  void dispose() async {
    _controller.dispose();
    WidgetsBinding.instance?.removeObserver(this);

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    //return the VlcPlayer Widget
    return VlcPlayer(
      controller: _controller,
      aspectRatio: 9 / 16,
      placeholder: const Center(child: CircularProgressIndicator()),
    );
  }
}

安卓配置权限-----------------------------

<!--应用程序需要使用摄像头设备-->
    <uses-feature android:name="android.hardware.camera"/>
    <!--应用程序用到摄像头-->
    <uses-feature android:name="android.hardware.camera.autofocus"></uses-feature>
    <!--视频、录音权限  请求音频捕获权限 -->
    <uses-permission android:name="android.permission.RECORD_VIDEO"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>

    <!--获取当前wifi状态 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <!--允许程序改变网络连接状态 -->
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <!--读取手机信息权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <!-- 上面xmlns:tools="http://schemas.android.com/tools" // 这里是新添加的即时通讯 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!--获取读写外置存储权限-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission
        android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <!--获取相机权限-->
    <uses-permission android:name="android.permission.CAMERA"/>
    <!--获取地址相关权限-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!-- 发送短信 -->
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <!-- 读取短信 -->
    <uses-permission android:name="android.permission.READ_SMS"/>
    <!-- 接收短信 -->
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>

    <!--通知-->
<!--    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>-->
<!--    <uses-permission android:name="android.permission.VIBRATE" />-->
    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
    <uses-permission android:name="android.permission.USE_EXACT_ALARM" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <!-- 获取通讯录权限 -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <!-- 语音识别相关权限 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!--修改声音设置信息-->
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />

    <!-- 扫描蓝牙设备或者操作蓝牙设置 -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <!-- 使用蓝牙的权限 -->
    <uses-permission android:name="android.permission.BLUETOOTH" />

    <!--精准定位权限,作用于Android6.0+ -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <!--模糊定位权限,作用于Android6.0+ -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

    <!--以下三个是Android12中新增,作用于Android12.0+ -->
    <!-- Android 12在不申请定位权限时,必须加上android:usesPermissionFlags="neverForLocation",否则搜不到设备 -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" tools:targetApi="s"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />

G:\gitflutter\flutter_parent_pro\android\app 下的build.gradle 配置


android {

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
//    lintOptions {
//        disable 'InvalidPackage'
//        checkReleaseBuilds false
//        abortOnError false
//    }

    //compileSdkVersion flutter.compileSdkVersion
    //compileSdkVersion 33
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {

        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.flutter_nft"
        //minSdkVersion flutter.minSdkVersion
        compileSdkVersion 32
        minSdkVersion 21
        targetSdkVersion 28
        //targetSdkVersion 19
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        //multiDexEnabled = true
//        ndk {
//            //选择要添加的对应 cpu 类型的 .so 库。
//            abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'
//            // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
//        }
//        manifestPlaceholders += [
//                JPUSH_PKGNAME : applicationId,
//                JPUSH_APPKEY : "e9a10f63233618fed62a4e83", //JPush上注册的包名对应的appkey.
//                JPUSH_CHANNEL : "developer-default",
//        ]
    }

    signingConfigs {

        release {
            keyAlias 'key'
            keyPassword 'gubanjie'
            storeFile file('keysss.jks')//此种写法默认key文件在android-app文件夹下
            storePassword 'gubanjie'
//            keyAlias keystoreProperties['keyAlias']
//            keyPassword keystoreProperties['keyPassword']
//            storeFile file(keystoreProperties['storeFile'])
//            storePassword keystoreProperties['storePassword']
        }
//        debug {
//            keyAlias 'key'
//            keyPassword 'gubanjie'
//            storeFile file('keysss.jks')
//            storePassword 'gubanjie'
////            keyAlias keystoreProperties['keyAlias']
////            keyPassword keystoreProperties['keyPassword']
////            storeFile file(keystoreProperties['storeFile'])
////            storePassword keystoreProperties['storePassword']
//        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
            //关闭混淆
            minifyEnabled false //删除无用代码
            shrinkResources false //删除无用资源
        }
        debug {
            signingConfig signingConfigs.release
        }
    }
    packagingOptions {
        exclude 'project.clj'
    }
}

ios配置---------------------- If you're unable to view media loaded from an external source, you should also add the following:

<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

For more information, or for more granular control over your App Transport Security (ATS) restrictions, you should read Apple's documentation.

Make sure that following line in <project root>/ios/Podfile uncommented:

platform :ios, '9.0'

NOTE: While the Flutter video_player is not functional on iOS Simulators, this package (flutter_vlc_playeris fully functional on iOS simulators.

To enable vlc cast functionality for external displays (chromecast), you should also add the following:

<key>NSLocalNetworkUsageDescription</key>
<string>Used to search for chromecast devices</string>
<key>NSBonjourServices</key>
<array>
  <string>_googlecast._tcp</string>
</array>

android

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

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