Flutter音视频录制与播放插件ijk_player_recorder的使用

Flutter音视频录制与播放插件ijk_player_recorder的使用

IJKPlayerRecorder

开始使用

本项目是一个为Flutter设计的插件,它提供了VideoView允许在Flutter上播放和录制RTSP流媒体。

如果您想获取IJKPlayerRecorder的配置,请从IJKPlayer源码获取,

对于仅适用于Android的应用,请从IJKPlayerRecorder获取。

目录

功能

  • ✅ 在Flutter上以低延迟播放RTSP视频
  • ✅ 支持Android播放和录制视频
  • [ ] 支持iOS:待办
  • [ ] 添加滤镜/效果到视频:目前不支持

需求

  • Flutter SDK: “>=2.12.0 <3.0.0”

使用方法

VideoViewController? _videoViewController;

...
Expanded(child: VideoView(
  onVideoViewCreatedCallback: (VideoViewController controller) {
    setState(() {
      _videoViewController = controller;
    });
  },
))
...

方法支持:

void startPreview() {
  _videoViewController?.start();
}

void stopPreview() {
  _videoViewController?.stopPlayback();
}

Future<void> startRecord() async {
  Directory appDocDir = await getApplicationDocumentsDirectory();
  setState(() {
    outVideo = appDocDir.path + "/a.mp4";
  });
  _videoViewController?.startRecord(outVideo);
}

void stopRecord() {
  _videoViewController?.stopRecord();
}

void setURL() {
  _videoViewController?.setVideoPath(videoURL);
}

示例

以下是一个完整的示例代码,展示如何使用ijk_player_recorder插件进行音视频录制和播放。

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

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:ijk_player_recorder/ijk_player_recorder.dart';
import 'package:ijk_player_recorder/video_view.dart';
import 'package:ijk_player_recorder/video_view_controller.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';
  String defaultValue = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
  String videoURL = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
  String outVideo = "";
  VideoViewController? _videoViewController;
  final textEditingController = TextEditingController();

  [@override](/user/override)
  void initState() {
    super.initState();
    initPlatformState();
    textEditingController.text = videoURL;
    textEditingController.addListener(_onTextChanged);
  }

  [@override](/user/override)
  void dispose() {
    cleanUp();
    super.dispose();
  }

  void cleanUp() {
    stopPreview();
    textEditingController.dispose();
  }

  void _onTextChanged() {
    print('Second text field: ${textEditingController.text}');
    String value = textEditingController.text;
    if (value.isEmpty) {
      videoURL = defaultValue;
    }
    setState(() {
      videoURL = value;
    });
  }

  // 平台消息是异步的,因此我们初始化在一个异步方法中。
  Future<void> initPlatformState() async {
    String platformVersion;
    // 平台消息可能会失败,所以我们使用try/catch PlatformException。
    // 我们还处理消息可能返回null的情况。
    try {
      platformVersion = await IjkPlayerRecorder.platformVersion ?? 'Unknown platform version';
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    // 如果小部件在异步平台消息还在飞行时被从树中移除,我们应该丢弃回复而不是调用setState来更新我们的非存在的外观。
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            children: [
              Row(
                children: [
                  Expanded(
                    child: TextField(
                      controller: textEditingController,
                    ),
                  ),
                ],
              ),
              Row(
                children: [
                  Text("输出视频路径:" + outVideo),
                ],
              ),
              Row(
                children: [
                  FlatButton(
                    onPressed: setURL,
                    child: Text("设置URL"),
                  ),
                  FlatButton(
                    onPressed: startPreview,
                    child: Text("开始预览"),
                  ),
                  FlatButton(
                    onPressed: stopPreview,
                    child: Text("停止预览"),
                  ),
                ],
              ),
              Row(
                children: [
                  FlatButton(
                    onPressed: startRecord,
                    child: Text("开始录制"),
                  ),
                  FlatButton(
                    onPressed: stopRecord,
                    child: Text("停止录制"),
                  ),
                ],
              ),
              Expanded(
                child: VideoView(
                  onVideoViewCreatedCallback: (VideoViewController controller) {
                    setState(() {
                      _videoViewController = controller;
                    });
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void startPreview() {
    _videoViewController?.start();
  }

  void stopPreview() {
    _videoViewController?.stopPlayback();
  }

  Future<void> startRecord() async {
    Directory appDocDir = await getApplicationDocumentsDirectory();
    setState(() {
      outVideo = appDocDir.path + "/a.mp4";
    });
    _videoViewController?.startRecord(outVideo);
  }

  void stopRecord() {
    _videoViewController?.stopRecord();
  }

  void setURL() {
    _videoViewController?.setVideoPath(videoURL);
  }
}

更多关于Flutter音视频录制与播放插件ijk_player_recorder的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter音视频录制与播放插件ijk_player_recorder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


ijk_player_recorder 是一个 Flutter 插件,用于在 Flutter 应用中实现音视频的录制和播放功能。它基于 ijkplayer,这是一个基于 FFmpeg 的轻量级 Android/iOS 播放器。以下是使用 ijk_player_recorder 插件的基本步骤。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 ijk_player_recorder 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  ijk_player_recorder: ^0.0.1  # 请使用最新版本

然后运行 flutter pub get 以获取依赖。

2. 配置 Android 和 iOS 项目

Android 配置

android/app/build.gradle 文件中,确保最低 SDK 版本为 21:

minSdkVersion 21

iOS 配置

ios/Podfile 中,确保最低 iOS 版本为 9.0:

platform :ios, '9.0'

然后运行 pod install 以安装 iOS 依赖。

3. 使用插件

播放视频

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

class VideoPlayerScreen extends StatefulWidget {
  @override
  _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  IjkPlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = IjkPlayerController.network(
      'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4',
    )..initialize().then((_) {
        setState(() {});
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Video Player'),
      ),
      body: Center(
        child: _controller.value.isInitialized
            ? AspectRatio(
                aspectRatio: _controller.value.aspectRatio,
                child: IjkPlayer(
                  controller: _controller,
                ),
              )
            : CircularProgressIndicator(),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }
}

录制视频

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

class VideoRecorderScreen extends StatefulWidget {
  @override
  _VideoRecorderScreenState createState() => _VideoRecorderScreenState();
}

class _VideoRecorderScreenState extends State<VideoRecorderScreen> {
  IjkRecorderController _recorderController;

  @override
  void initState() {
    super.initState();
    _recorderController = IjkRecorderController();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Video Recorder'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            IjkRecorder(
              controller: _recorderController,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                await _recorderController.startRecording();
              },
              child: Text('Start Recording'),
            ),
            ElevatedButton(
              onPressed: () async {
                await _recorderController.stopRecording();
              },
              child: Text('Stop Recording'),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _recorderController.dispose();
  }
}

4. 权限处理

Android

AndroidManifest.xml 中添加以下权限:

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

iOS

Info.plist 中添加以下权限:

<key>NSCameraUsageDescription</key>
<string>We need access to your camera to record video.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need access to your microphone to record audio.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to save videos.</string>

5. 运行项目

确保所有配置都正确后,运行你的 Flutter 项目:

flutter run
回到顶部