Flutter插件yourinrolltoolsstream的介绍与使用

发布于 1周前 作者 yuanlaile 最后一次编辑是 5天前 来自 Flutter

Flutter插件yourinrolltoolsstream的介绍与使用

yourinrolltoolsstream 版本: 1.1.5

此插件是 flutter 的 camera 插件的扩展,用于添加 RTMP 流媒体功能。它支持 Android 和 iOS(不支持 Web)。

获取开始

该插件的 API 与 camera 插件完全相同,安装要求也相同。唯一的区别是多了一个额外的 API startStreaming(url),它接受一个 RTMP URL 并开始向该特定 URL 流式传输。

对于 Android,我们使用了 rtmp-rtsp-stream-client-java,而对于 iOS,则使用了 HaishinKit.swift


功能

  • 在小部件中显示实时相机预览。
  • 可以捕获快照并保存到文件。
  • 录制视频。
  • 从 Dart 访问图像流。

Flutter插件yourinrolltoolsstream的安装

首先,在 pubspec.yaml 文件中添加 camera 依赖。

iOS

ios/Runner/Info.plist 中添加以下两行:

  • 一个键为 Privacy - Camera Usage Description 的条目,带有一个描述。
  • 一个键为 Privacy - Microphone Usage Description 的条目,带有一个描述。

或者以文本格式添加以下内容:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
<key>NSPhotoLibraryUsageDescription</key>
<string></string>
<key>UIBackgroundModes</key>
<array>
    <string>processing</string>
</array>
<key>NSCameraUsageDescription</key>
<string>App requires access to the camera for live streaming feature.</string>
<key>NSMicrophoneUsageDescription</key>
<string>App requires access to the microphone for live streaming feature.</string>

Android

android/app/build.gradle 文件中将最小 Android SDK 版本更改为 21 或更高版本:

minSdkVersion 21

还需要在打包选项中添加一段代码以排除一个文件,否则构建时会报错:

packagingOptions {
   exclude 'project.clj'
}

示例代码

以下是完整的示例代码,展示了如何使用 yourinrolltoolsstream 插件进行 RTMP 视频流传输。

// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';
import 'package:yourinrolltoolsstream/camera.dart';
import 'package:wakelock/wakelock.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

class RtmpVideoStreamPage extends StatefulWidget {
  final int userId;
  final int pageIndex;

  const RtmpVideoStreamPage({required this.userId, required this.pageIndex});

  [@override](/user/override)
  State<RtmpVideoStreamPage> createState() => _RtmpVideoStreamPageState();
}

class _RtmpVideoStreamPageState extends State<RtmpVideoStreamPage> {
  CameraController? controller;
  String? streamURL;
  bool streaming = false;

  [@override](/user/override)
  void initState() {
    super.initState();
    loadUserData();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
  }

  void loadUserData() async {
    String token = 'your_token_here'; // 替换为实际的 token
    String decodedStreamKey = generateMd5(token);
    streamURL = "rtmp://youinroll.com:1935/stream/$decodedStreamKey";
  }

  String generateMd5(String input) {
    return md5.convert(utf8.encode(input)).toString();
  }

  void onVideoStreamingButtonPressed() async {
    if (controller == null) return;

    try {
      await controller!.startVideoStreaming(streamURL!);
      Wakelock.enable(); // 启用屏幕常亮
      setState(() {
        streaming = true;
      });
    } catch (e) {
      print("Error starting stream: $e");
    }
  }

  void onStopButtonPressed() async {
    if (controller == null) return;

    try {
      await controller!.stopVideoStreaming();
      Wakelock.disable(); // 禁用屏幕常亮
      setState(() {
        streaming = false;
      });
    } catch (e) {
      print("Error stopping stream: $e");
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('RTMP Video Streaming'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: streaming ? onStopButtonPressed : onVideoStreamingButtonPressed,
              child: Text(streaming ? 'Stop Streaming' : 'Start Streaming'),
            ),
            SizedBox(height: 20),
            Text(
              'Stream URL: $streamURL',
              style: TextStyle(fontSize: 16),
            ),
          ],
        ),
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    if (controller != null) {
      controller?.dispose();
    }
    Wakelock.disable();
    super.dispose();
  }
}

void main() {
  runApp(MaterialApp(home: RtmpVideoStreamPage(userId: 123, pageIndex: 1)));
}

更多关于Flutter插件yourinrolltoolsstream的介绍与使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!