dart_vlc

pub package CI/CD Donate

适用于 Windows、Linux 和 macOS 的 Flutter 媒体播放、广播、录制和 Chromecast 库。

使用 libVLC & libVLC++ 以 C++ 编写。

安装

Flutter

dependencies:
  ...
  dart_vlc: ^0.1.6

Dart CLI

dependencies:
  ...
  dart_vlc_ffi: ^0.1.3

关于 Dart CLI 实现的更多信息,请访问 此处

如果您发现 bug 或需要帮助,请随时 提出新 issue讨论

支持

请通过 star 仓库或请我喝杯咖啡来支持该项目。

Donate
Donate

非常感谢您的支持。Android 支持即将推出。

文档

查看 设置 部分以在您的平台上配置插件。

初始化库

void main() {
  DartVLC.initialize();
  runApp(MyApp());
}

创建一个新的播放器实例。

Player player = Player(id: 69420);

要传递 VLC CLI 参数,请使用 commandlineArguments 参数。

Player player = Player(
  id: 69420,
  commandlineArguments: ['--no-video']
);

创建一个媒体用于播放。

Media media0 = Media.file(
  File('C:/music.mp3')
);

Media media1 = Media.asset(
  'assets/audio/example.mp3'
);

Media media2 = Media.network(
  'https://www.example.com/music.aac'
);

// Clip the media.
Media media2 = Media.network(
  'https://www.example.com/music.aac',
  startTime: Duration(seconds: 20), // Start media from 20 seconds from the beginning.
  stopTime: Duration(seconds: 60), // End media at 60 seconds from the beginning. 
);

使用播放列表创建媒体列表。

Playlist playlist = new Playlist(
  medias: [
    Media.file(File('C:/music.mp3')),
    Media.file(File('C:/audio.mp3')),
    Media.asset('assets/audio/example.mp3'),
    Media.network('https://www.example.com/music.aac'),
  ],
);

将媒体或播放列表打开到播放器中。

player.open(
  Media.file(File('C:/music0.mp3')),
  autoStart: true, // default
);

player.open(
  Playlist(
    medias: [
      Media.file(new File('C:/music0.mp3')),
      Media.file(new File('C:/music1.mp3')),
      Media.file(new File('C:/music2.mp3')),
    ],
  ),
  autoStart: false,
);

控制播放。

player.play();

player.seek(Duration(seconds: 30));

player.pause();

player.playOrPause();

player.stop();

遍历播放列表。

player.next();

player.back();

player.jump(10);

操作正在播放的播放列表。

player.add(
  Media.file(File('C:/music0.mp3')),
);

player.remove(4);

player.insert(
  2,
  Media.file(File('C:/music0.mp3')),
);

player.move(0, 4);

设置播放音量和速率。

player.setVolume(0.5);

player.setRate(1.25);

获取和更改播放设备。

List<Device> devices = Devices.all;

player.setDevice(
  devices[0],
);

保存视频快照

player.takeSnapshot(file, 1920, 1080);

在 widget 树中显示视频。

Widget 树中显示 Video

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Video(
        player: player,
        height: 1920.0,
        width: 1080.0,
        scale: 1.0, // default
        showControls: false, // default
      ),
    );
  }
}

默认情况下,Video widget 的帧大小将适应当前播放的视频。
要覆盖此设置并定义自定义视频帧大小,请在实例化 Player 类时传递 videoDimensions 参数,如下所示。

Player player = Player(
  id: 69420,
  videoDimensions: const VideoDimensions(640, 360)
);

感谢 @tomassasovskyVideo widget 添加视觉控件。

更改用户代理

player.setUserAgent(userAgent);

检索媒体元数据。

Media media = Media.network(
  'https://www.example.com/media.mp3',
  parse: true,
  timeout: Duration(seconds: 10),
);

Map<String, String> metas = media.metas;

监听播放事件。

(无需依赖流,可以直接从 Player 实例检索相同信息)。

监听当前加载的媒体和播放列表索引的变化。

player.currentStream.listen((CurrentState state) {
  state.index;
  state.media;
  state.medias;
  state.isPlaylist;
});

监听播放位置和媒体时长。

player.positionStream.listen((PositionState state) {
  state.position;
  state.duration;
});

监听播放状态。

player.playbackStream.listen((PlaybackState state) {
  state.isPlaying;
  state.isSeekable;
  state.isCompleted;
});

监听 Player 的音量和速率。

player.generalStream.listen((GeneralState state) {
  state.volume;
  state.rate;
});

监听当前播放 Video 的尺寸。

player.videoDimensionsStream.listen((VideoDimensions video) {
  video.width;
  video.height;
});

监听正在播放的 Media 的缓冲进度。

player.bufferingProgressStream.listen(
  (double event) {
    this.setState(() {
      this.bufferingProgress = event;
    });
  },
);

设置均衡器。

使用预设创建。

Equalizer equalizer = Equalizer.createMode(EqualizerMode.party);
player.setEqualizer(equalizer);

创建自定义均衡器。

Equalizer equalizer = Equalizer.createEmpty();
equalizer.setPreAmp(10.0);
equalizer.setBandAmp(31.25, -10.0);
equalizer.setBandAmp(100.0, -10.0);
player.setEqualizer(equalizer);

获取均衡器状态。

equalizer.preAmp;
equalizer.bandAmps;

广播媒体。

广播到本地主机。

Broadcast broadcast = Broadcast.create(
  id: 0,
  media: Media.file(File('C:/video.mp4')),
  configuration: BroadcastConfiguration(
    access: 'http',
    mux: 'mpeg1',
    dst: '127.0.0.1:8080',
    vcodec: 'mp1v',
    vb: 1024,
    acodec: 'mpga',
    ab: 128,
  ),
);
broadcast.start();

Dispose Broadcast 实例以释放资源。

broadcast.dispose();

录制媒体。

感谢 @DomingoMG 添加 RecordChromecast 类。

Record record = Record.create(
  id: 205, 
  media: Media.network('https://www.example.com/streaming-media.MP3'), 
  pathFile: '/home/alexmercerind/recording.MP3',
);
record.start();

设置

Windows

一切都已设置就绪。

macOS

要在 macOS 上运行,请通过 Homebrew 安装 CMake

brew install cmake

如果在归档过程中遇到 cmake: command not found 错误

  1. 下载 CMake 并将其移动到 Applications 文件夹。
  2. 运行

sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install

Linux

要在 Linux 上使用此插件,您必须安装 VLClibVLC

在 Ubuntu/Debian 上

sudo apt-get install vlc

sudo apt-get install libvlc-dev

在 Fedora 上

sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm

sudo dnf install vlc

sudo dnf install vlc-devel

iOS [进行中]

为整个项目禁用 bitcode 生成,MobileVLC 才能正常工作。
将以下内容添加到 iOS Flutter 项目的 Podfile 中,该文件位于 post_install 函数中。有关参考,请查看示例项目中的 Podfile

target.build_configurations.each do |config|
    config.build_settings['ENABLE_BITCODE'] = 'NO'
end

要使示例项目正常工作,您需要为 Xcode 项目配置真实设备,或者在 ios/dart_vlc.podspec 中注释掉构建脚本 Build Device lib

示例

您可以在 此处 查看示例项目。

dart_vlc 在 Ubuntu Linux 上运行。

工作原理

该存储库包含一个基于 libVLC++ 的 C++ 包装器。这使得事件和控件的处理更加容易,并具有额外的功能。
我倾向于在 C++ 中处理大部分逻辑,因此 Dart 代码非常少,并且映射也很少。

该项目可能看起来像一个 Flutter 插件,但它基于 FFI。 此处 是 FFI 绑定到 C++ 包装器 的文件,所有平台共享这些文件,Dart CLI 应用也可以使用。平台通道接口仅用于 [flutter]

进度

已完成

  • File 进行 Media 播放。
  • 从网络进行 Media 播放。
  • 从资源进行 Media 播放。
  • play/pause/playOrPause/stop
  • 多个 Player 实例。
  • 播放列表.
  • 播放列表的 next/back/jump
  • setVolume.
  • setRate.
  • seek.
  • 事件。
  • 自动获取头文件、库和共享库。
  • 通过 CMake 更改 VLC 版本。
  • 事件流。
    • Player.currentState
      • index:当前 Playlist 中媒体的索引。
      • medias:所有已打开 Media 的列表。
      • media:当前正在播放的 Media
      • isPlaylist:加载的是单个 Media 还是 Playlist
    • Player.positionState
      • position:当前播放媒体在 Duration 中的位置。
      • duration:当前播放媒体在 Duration 中的位置。
    • Player.playbackState
      • isPlaying.
      • isSeekable.
      • isCompleted.
    • Player.generalState
      • volume:当前 Player 实例的音量。
      • rate:当前 Player 实例的速率。
  • 播放期间在 PlaylistMediaadd/insert/remove/move
  • 设备枚举和更改。
  • 检索 MediaMeta
  • Video 嵌入 Flutter 窗口中。
  • 支持直播流链接。
  • 用于广播 MediaBroadcast 类。
  • 用于录制 MediaRecord 类。
  • Chromecast 类。
  • Equalizer 支持。
  • Media.network 添加头部信息 (不可行,已添加用户代理)。
  • 切换到 FFI 以获得更多跨平台自由度。
  • 根据视频更改 Video 的帧大小。
  • 保存快照。

进行中或计划中的功能 (顺序不分先后)...

  • 移除 libVLC++ 依赖 (可能)。
  • 字幕控制。
  • 音频轨道控制。
  • 写入元数据标签。
  • 提高效率。
  • 支持原生音量控制/锁屏通知 (可能)。
  • 将项目移植到其他平台,如 Android/iOS (可能)。
  • 用于 Media 播放控制的 D-Bus MPRIS 控制 (可能)。

致谢

首先,感谢 VideoLAN 团队创建 libVLClibVLC++。他们是非常棒的团队,在他们的工作中非常出色。

感谢 @jnschulze 为该项目以及 Flutter 引擎本身做出的杰出贡献,例如添加纹理支持。

感谢 @krjw-eyev 致力于 iOS 支持。

感谢 @jnschulze@namniav 致力于 macOS 支持。

感谢 The Flutter Team@stuartmorgan 对项目的意见支持。

感谢 libVLC 社区的以下成员 (顺序不分先后),他们提供了关于 libVLC API 的一般性想法。

贡献

项目中的代码组织良好,并遵循清洁架构。

项目贡献开放,如果您先在 issues 中讨论 bug 修复/功能添加,我们将不胜感激。

许可证

Copyright (C) 2021, Hitesh Kumar Saini [email protected]

本库及本仓库下的作品在 GNU Lesser General Public License v2.1 下许可。

愿景

目前还没有适用于 Flutter 或 Dart 在 Windows/Linux 上进行媒体 (音频或视频) 播放的库。所以,这个项目就是关于这个的。
正如人们可能已经知道的,VLC 是目前最好的媒体播放工具之一。

所以,现在您可以使用它从 Flutter 或 Dart 应用播放音频或视频文件。

随着项目的增长,社区中的优秀人士也为 iOS 和 macOS 添加了支持。

GitHub

https://github.com/alexmercerind/dart_vlc