flutter端的AVFoundationVideoPlayer
是实现PlatformInterface
接口的插件。它就是flutter端跟原生端通信的桥梁。
AVFoundationVideoPlayer
scss
/// iOS平台的视频播放器实现,使用Pigeon生成的VideoPlayerApi
class AVFoundationVideoPlayer extends VideoPlayerPlatform {
/// 创建一个新的基于AVFoundation的视频播放器实现实例
AVFoundationVideoPlayer({
@visibleForTesting AVFoundationVideoPlayerApi? pluginApi,
@visibleForTesting VideoPlayerInstanceApi Function(int playerId)? playerProvider,
}) : _api = pluginApi ?? AVFoundationVideoPlayerApi(),
_playerProvider = playerProvider ?? _productionApiProvider;
final AVFoundationVideoPlayerApi _api;
// 用于创建VideoPlayerInstanceApi实例的方法,可以在测试中被重写
final VideoPlayerInstanceApi Function(int mapId) _playerProvider;
/// 将播放器ID与视图状态关联的映射表
/// 用于确定构建视图时使用哪种视图类型
@visibleForTesting
final Map<int, VideoPlayerViewState> playerViewStates = <int, VideoPlayerViewState>{};
final Map<int, VideoPlayerInstanceApi> _players = <int, VideoPlayerInstanceApi>{};
/// 将此类注册为VideoPlayerPlatform的默认实例
static void registerWith() {
VideoPlayerPlatform.instance = AVFoundationVideoPlayer();
}
@override
Future<void> init() {
return _api.initialize();
}
@override
Future<void> dispose(int playerId) async {
final VideoPlayerInstanceApi? player = _players.remove(playerId);
await player?.dispose();
playerViewStates.remove(playerId);
}
@override
Future<int?> create(DataSource dataSource) async {
return createWithOptions(
VideoCreationOptions(
dataSource: dataSource,
// 在引入createWithOptions之前,纹理视图是唯一支持的视图类型
viewType: VideoViewType.textureView,
),
);
}
@override
Future<int?> createWithOptions(VideoCreationOptions options) async {
final DataSource dataSource = options.dataSource;
final VideoViewType viewType = options.viewType;
String? uri;
switch (dataSource.sourceType) {
case DataSourceType.asset:
final String? asset = dataSource.asset;
if (asset == null) {
throw ArgumentError('"asset"对于资源数据源必须非空');
}
uri = await _api.getAssetUrl(asset, dataSource.package);
if (uri == null) {
// 为了与之前的实现兼容,抛出平台异常
throw PlatformException(code: 'video_player', message: '在包${dataSource.package}中找不到资源$asset');
}
case DataSourceType.network:
case DataSourceType.file:
case DataSourceType.contentUri:
uri = dataSource.uri;
}
if (uri == null) {
throw ArgumentError('无法从$options构造视频资源');
}
final CreationOptions pigeonCreationOptions = CreationOptions(uri: uri, httpHeaders: dataSource.httpHeaders);
final int playerId;
final VideoPlayerViewState state;
switch (viewType) {
case VideoViewType.textureView:
final TexturePlayerIds ids = await _api.createForTextureView(pigeonCreationOptions);
playerId = ids.playerId;
state = VideoPlayerTextureViewState(textureId: ids.textureId);
case VideoViewType.platformView:
playerId = await _api.createForPlatformView(pigeonCreationOptions);
state = const VideoPlayerPlatformViewState();
}
playerViewStates[playerId] = state;
ensureApiInitialized(playerId);
return playerId;
}
/// 返回playerId对应的API实例,如果不存在则创建它
@visibleForTesting
VideoPlayerInstanceApi ensureApiInitialized(int playerId) {
return _players.putIfAbsent(playerId, () {
return _playerProvider(playerId);
});
}
@override
Future<void> setLooping(int playerId, bool looping) {
return _playerWith(id: playerId).setLooping(looping);
}
@override
Future<void> play(int playerId) {
return _playerWith(id: playerId).play();
}
@override
Future<void> pause(int playerId) {
return _playerWith(id: playerId).pause();
}
@override
Future<void> setVolume(int playerId, double volume) {
return _playerWith(id: playerId).setVolume(volume);
}
@override
Future<void> setPlaybackSpeed(int playerId, double speed) {
assert(speed > 0);
return _playerWith(id: playerId).setPlaybackSpeed(speed);
}
@override
Future<void> seekTo(int playerId, Duration position) {
return _playerWith(id: playerId).seekTo(position.inMilliseconds);
}
@override
Future<Duration> getPosition(int playerId) async {
final int position = await _playerWith(id: playerId).getPosition();
return Duration(milliseconds: position);
}
@override
Stream<VideoEvent> videoEventsFor(int playerId) {
debugPrint('---✅dart启动视频播放器流监听videoEventsFor, playerId: $playerId✅---');
return _eventChannelFor(playerId).receiveBroadcastStream().map((dynamic event) {
final Map<dynamic, dynamic> map = event as Map<dynamic, dynamic>;
debugPrint('---✅dart视频播放器流监听videoEventsFor结果, map: $map✅---');
return switch (map['event']) {
'initialized' => VideoEvent(
eventType: VideoEventType.initialized,
duration: Duration(milliseconds: map['duration'] as int),
size: Size((map['width'] as num?)?.toDouble() ?? 0.0, (map['height'] as num?)?.toDouble() ?? 0.0),
),
'completed' => VideoEvent(eventType: VideoEventType.completed),
'bufferingUpdate' => VideoEvent(
buffered: (map['values'] as List<dynamic>).map<DurationRange>(_toDurationRange).toList(),
eventType: VideoEventType.bufferingUpdate,
),
'bufferingStart' => VideoEvent(eventType: VideoEventType.bufferingStart),
'bufferingEnd' => VideoEvent(eventType: VideoEventType.bufferingEnd),
'isPlayingStateUpdate' => VideoEvent(eventType: VideoEventType.isPlayingStateUpdate, isPlaying: map['isPlaying'] as bool),
_ => VideoEvent(eventType: VideoEventType.unknown),
};
});
}
@override
Future<void> setMixWithOthers(bool mixWithOthers) {
return _api.setMixWithOthers(mixWithOthers);
}
@override
Widget buildView(int playerId) {
return buildViewWithOptions(VideoViewOptions(playerId: playerId));
}
@override
Widget buildViewWithOptions(VideoViewOptions options) {
final int playerId = options.playerId;
final VideoPlayerViewState? viewState = playerViewStates[playerId];
return switch (viewState) {
VideoPlayerTextureViewState(:final int textureId) => Texture(textureId: textureId),
VideoPlayerPlatformViewState() => _buildPlatformView(playerId),
null => throw Exception('找不到playerId对应的视图类型: $playerId'),
};
}
Widget _buildPlatformView(int playerId) {
final PlatformVideoViewCreationParams creationParams = PlatformVideoViewCreationParams(playerId: playerId);
return IgnorePointer(
// 使用IgnorePointer以便在平台视图上方使用GestureDetector
child: UiKitView(
viewType: 'plugins.flutter.dev/video_player_ios',
creationParams: creationParams,
creationParamsCodec: AVFoundationVideoPlayerApi.pigeonChannelCodec,
),
);
}
EventChannel _eventChannelFor(int playerId) {
return EventChannel('flutter.io/videoPlayer/videoEvents$playerId');
}
VideoPlayerInstanceApi _playerWith({required int id}) {
final VideoPlayerInstanceApi? player = _players[id];
return player ?? (throw StateError('没有ID为$id的活跃播放器'));
}
DurationRange _toDurationRange(dynamic value) {
final List<dynamic> pair = value as List<dynamic>;
final int startMilliseconds = pair[0] as int;
final int durationMilliseconds = pair[1] as int;
return DurationRange(
Duration(milliseconds: startMilliseconds),
Duration(milliseconds: startMilliseconds + durationMilliseconds),
);
}
}
AVFoundationVideoPlayerApi
php
/**
* AVFoundation视频播放器API
*
* 这是一个由Pigeon工具自动生成的类,用于Flutter与原生iOS/macOS平台之间的通信。
* 该类提供了视频播放器的核心平台级别操作接口。
*
* 主要功能:
* 1. 播放器初始化和生命周期管理
* 2. 创建不同渲染模式的播放器(平台视图/纹理视图)
* 3. 音频会话配置管理
* 4. Flutter资源文件路径解析
*
* 通信机制:
* - 使用BasicMessageChannel进行跨平台消息传递
* - 支持异步操作和错误处理
* - 自动处理数据序列化和反序列化
*/
class AVFoundationVideoPlayerApi {
/// AVFoundationVideoPlayerApi构造函数
///
/// [binaryMessenger] 二进制消息传递器参数,用于依赖注入。
/// 如果为null,将使用默认的BinaryMessenger路由到宿主平台。
///
/// [messageChannelSuffix] 消息通道后缀,用于区分不同的API实例
AVFoundationVideoPlayerApi({
BinaryMessenger? binaryMessenger,
String messageChannelSuffix = '',
}) : pigeonVar_binaryMessenger = binaryMessenger,
pigeonVar_messageChannelSuffix =
messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
/// 二进制消息传递器实例,用于与原生平台通信
final BinaryMessenger? pigeonVar_binaryMessenger;
/// Pigeon消息编解码器,处理数据类型转换
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
/// 消息通道后缀,用于标识特定的API实例
final String pigeonVar_messageChannelSuffix;
/**
* 初始化AVFoundation视频播放器插件
*
* 这是使用播放器之前必须调用的方法,用于:
* - 设置AVFoundation框架的基础配置
* - 初始化音频会话
* - 准备播放器工厂和相关组件
*
* @return Future<void> 异步操作完成标识
* @throws PlatformException 当初始化失败时抛出平台异常
*/
Future<void> initialize() async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.initialize$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
/**
* 创建使用平台视图渲染的视频播放器
*
* 平台视图模式特点:
* - 使用原生UIView/NSView进行渲染
* - 更好的兼容性,支持所有视频格式和特性
* - 可能存在性能开销和层级问题
* - 适用于需要完整原生功能的场景
*
* @param params 创建选项,包含视频URI和HTTP头信息
* @return Future<int> 返回创建的播放器ID
* @throws PlatformException 当创建失败时抛出异常
*/
Future<int> createForPlatformView(CreationOptions params) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForPlatformView$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
<Object?>[params],
);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else if (pigeonVar_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as int?)!;
}
}
/**
* 创建使用纹理渲染的视频播放器
*
* 纹理模式特点:
* - 使用Flutter的Texture Widget进行渲染
* - 更好的性能表现和Flutter集成
* - 支持Flutter的变换、动画等效果
* - 可能在某些特殊视频格式上有限制
* - 推荐用于大多数常规播放场景
*
* @param creationOptions 创建选项,包含视频URI和HTTP头信息
* @return Future<TexturePlayerIds> 返回包含播放器ID和纹理ID的对象
* @throws PlatformException 当创建失败时抛出异常
*/
Future<TexturePlayerIds> createForTextureView(
CreationOptions creationOptions,
) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForTextureView$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
<Object?>[creationOptions],
);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else if (pigeonVar_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as TexturePlayerIds?)!;
}
}
/**
* 设置音频混合模式
*
* 控制视频播放器的音频是否与其他应用的音频混合播放:
* - true: 允许与其他音频混合(如音乐应用、通话等)
* - false: 独占音频输出,会暂停其他应用的音频
*
* 使用场景:
* - 背景音乐播放:设置为true,允许与系统音频混合
* - 视频通话、游戏:设置为false,获得独占音频控制
*
* @param mixWithOthers 是否允许与其他音频混合
* @return Future<void> 异步操作完成标识
* @throws PlatformException 当设置失败时抛出异常
*/
Future<void> setMixWithOthers(bool mixWithOthers) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setMixWithOthers$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
<Object?>[mixWithOthers],
);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
/**
* 获取Flutter资源文件的本地URL路径
*
* 将Flutter项目中的资源文件路径转换为原生平台可访问的本地文件URL。
* 这对于播放打包在应用内的视频文件非常重要。
*
* 资源路径解析过程:
* 1. 根据资源名称在Flutter资源清单中查找
* 2. 考虑包名(如果指定)进行路径解析
* 3. 返回原生平台可直接访问的file:// URL
*
* @param asset 资源文件名称(如 "videos/sample.mp4")
* @param package 可选的包名,用于访问其他包中的资源
* @return Future<String?> 返回本地文件URL,如果资源不存在则返回null
* @throws PlatformException 当路径解析失败时抛出异常
*/
Future<String?> getAssetUrl(String asset, String? package) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.getAssetUrl$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
<Object?>[asset, package],
);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return (pigeonVar_replyList[0] as String?);
}
}
}
VideoPlayerInstanceApi
ini
/**
* 视频播放器实例API
*
* 这是一个由Pigeon工具自动生成的类,用于控制单个视频播放器实例的播放行为。
* 该类提供了视频播放器的核心控制功能,每个播放器实例都有一个对应的API实例。
*
* 主要功能:
* 1. 播放控制(播放、暂停、跳转)
* 2. 播放参数设置(音量、播放速度、循环模式)
* 3. 播放状态查询(当前播放位置)
* 4. 资源管理(释放播放器资源)
*
* 使用方式:
* - 通过AVFoundationVideoPlayerApi创建播放器后获得实例
* - 使用messageChannelSuffix区分不同的播放器实例
* - 所有操作都是异步的,返回Future对象
*/
class VideoPlayerInstanceApi {
/// VideoPlayerInstanceApi构造函数
///
/// [binaryMessenger] 二进制消息传递器参数,用于依赖注入。
/// 如果为null,将使用默认的BinaryMessenger路由到宿主平台。
///
/// [messageChannelSuffix] 消息通道后缀,用于标识特定的播放器实例
/// 通常使用播放器ID作为后缀,确保每个播放器实例有独立的通信通道
VideoPlayerInstanceApi({
BinaryMessenger? binaryMessenger,
String messageChannelSuffix = '',
}) : pigeonVar_binaryMessenger = binaryMessenger,
pigeonVar_messageChannelSuffix =
messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
/// 二进制消息传递器实例,用于与原生平台通信
final BinaryMessenger? pigeonVar_binaryMessenger;
/// Pigeon消息编解码器,处理数据类型转换
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
/// 消息通道后缀,用于标识特定的播放器实例
final String pigeonVar_messageChannelSuffix;
/**
* 设置视频循环播放模式
*
* 控制视频播放完成后的行为:
* - true: 视频播放完成后自动重新开始播放,形成无限循环
* - false: 视频播放完成后停止,不会自动重播
*
* 使用场景:
* - 背景视频、装饰性视频:通常设置为true,持续循环播放
* - 教学视频、宣传片:通常设置为false,播放完成后停止
* - 短视频应用:可根据用户设置或内容类型动态调整
*
* @param looping 是否启用循环播放
* @return Future<void> 异步操作完成标识
* @throws PlatformException 当设置失败时抛出异常
*/
Future<void> setLooping(bool looping) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setLooping$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
<Object?>[looping],
);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
/**
* 设置视频播放音量
*
* 调整当前播放器实例的音频输出音量大小。
* 这个设置只影响当前播放器,不会改变系统全局音量。
*
* 音量范围和效果:
* - 0.0: 完全静音,无音频输出
* - 1.0: 最大音量,使用视频原始音频级别
* - 0.0-1.0之间: 按比例调整音量大小
* - 超出范围的值会被自动限制在有效范围内
*
* 使用场景:
* - 多媒体应用中的音量控制滑块
* - 背景视频的音量调节
* - 音频淡入淡出效果实现
*
* @param volume 音量值,范围0.0-1.0
* @return Future<void> 异步操作完成标识
* @throws PlatformException 当设置失败时抛出异常
*/
Future<void> setVolume(double volume) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setVolume$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
<Object?>[volume],
);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
/**
* 设置视频播放速度
*
* 调整视频播放的速率,可以实现快进、慢放、倒放等效果。
* 播放速度的改变会同时影响视频和音频的播放速率。
*
* 速度值说明:
* - 1.0: 正常播放速度(默认值)
* - 0.5: 半速播放(慢放)
* - 2.0: 双倍速播放(快进)
* - 0.0: 暂停播放
* - 负值: 倒放(部分平台支持)
*
* 常用速度设置:
* - 0.25x, 0.5x, 0.75x: 慢速播放,适用于学习、分析场景
* - 1.25x, 1.5x, 2.0x: 快速播放,适用于快速浏览
* - 变速播放在在线教育、体育分析等场景中非常有用
*
* @param speed 播放速度倍率
* @return Future<void> 异步操作完成标识
* @throws PlatformException 当设置失败时抛出异常
*/
Future<void> setPlaybackSpeed(double speed) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setPlaybackSpeed$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
<Object?>[speed],
);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
/**
* 开始播放视频
*
* 启动或恢复视频播放。如果视频处于暂停状态,将从当前位置继续播放;
* 如果视频尚未开始,将从头开始播放。
*
* 播放行为说明:
* - 首次调用:从视频开头开始播放
* - 暂停后调用:从暂停位置继续播放
* - 播放完成后调用:根据循环设置决定是否重新播放
* - 可以在视频加载过程中调用,播放器会在准备就绪后自动开始
*
* 注意事项:
* - 某些平台可能需要用户交互才能开始播放(自动播放策略)
* - 网络视频需要缓冲时间,可能不会立即开始播放
* - 播放状态变化会通过事件流通知Flutter层
*
* @return Future<void> 异步操作完成标识
* @throws PlatformException 当播放启动失败时抛出异常
*/
Future<void> play() async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.play$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
/**
* 获取当前播放位置
*
* 返回视频当前的播放进度,以毫秒为单位。
* 这个值表示从视频开始到当前播放点的时间长度。
*
* 返回值说明:
* - 返回值为毫秒数(int类型)
* - 视频开始位置为0
* - 播放过程中该值会持续增加
* - 跳转后会立即反映新的位置
*
* 使用场景:
* - 实现播放进度条显示
* - 保存播放断点,支持续播功能
* - 实现播放时间显示(需要转换为时分秒格式)
* - 同步多个播放器的播放进度
*
* 注意事项:
* - 频繁调用可能影响性能,建议配合定时器适度查询
* - 网络视频的位置可能不够精确,存在缓冲影响
*
* @return Future<int> 当前播放位置(毫秒)
* @throws PlatformException 当获取位置失败时抛出异常
*/
Future<int> getPosition() async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.getPosition$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else if (pigeonVar_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as int?)!;
}
}
/**
* 跳转到指定播放位置
*
* 将视频播放位置跳转到指定的时间点。这是一个异步操作,
* 跳转完成后播放器会从新位置继续播放或保持暂停状态。
*
* 参数说明:
* - position: 目标位置,以毫秒为单位
* - 可以跳转到视频的任意有效位置
* - 超出视频长度的值会被限制到视频末尾
* - 负值会被限制到视频开头(0位置)
*
* 跳转行为:
* - 播放中跳转:会在新位置继续播放
* - 暂停中跳转:会跳转到新位置但保持暂停状态
* - 网络视频跳转:可能需要重新缓冲
*
* 使用场景:
* - 进度条拖拽跳转
* - 章节跳转功能
* - 续播功能(跳转到上次播放位置)
* - 精确定位到特定时间点
*
* @param position 目标播放位置(毫秒)
* @return Future<void> 异步操作完成标识
* @throws PlatformException 当跳转失败时抛出异常
*/
Future<void> seekTo(int position) async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.seekTo$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
<Object?>[position],
);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
/**
* 暂停视频播放
*
* 暂停当前正在播放的视频,保持在当前播放位置。
* 暂停后可以通过调用play()方法从当前位置恢复播放。
*
* 暂停行为说明:
* - 立即停止视频和音频播放
* - 保持当前播放位置不变
* - 可以多次调用,不会产生副作用
* - 如果视频已经暂停,调用此方法无效果
*
* 使用场景:
* - 用户主动暂停播放
* - 应用进入后台时自动暂停
* - 接收到电话等中断事件时暂停
* - 实现播放/暂停切换功能
*
* 与其他操作的关系:
* - 暂停后仍可以调用seekTo()跳转位置
* - 暂停后可以调用setVolume()等设置方法
* - 播放状态变化会通过事件流通知Flutter层
*
* @return Future<void> 异步操作完成标识
* @throws PlatformException 当暂停操作失败时抛出异常
*/
Future<void> pause() async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.pause$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
/**
* 释放播放器资源
*
* 彻底释放当前播放器实例占用的所有系统资源,包括内存、解码器、
* 网络连接等。调用此方法后,播放器实例将不再可用。
*
* 释放操作包括:
* - 停止视频播放和音频输出
* - 释放视频解码器和音频解码器
* - 关闭网络连接和文件句柄
* - 清理缓存和临时数据
* - 注销事件监听器和KVO观察者
*
* 调用时机:
* - 播放器不再需要时(如页面销毁)
* - 应用内存不足时主动释放
* - 切换到新的视频源之前
* - 应用进入后台长时间不使用时
*
* 重要注意事项:
* - 调用dispose()后不能再使用此播放器实例
* - 必须在适当的时机调用,避免内存泄漏
* - Flutter Widget销毁时应确保调用此方法
* - 这是一个不可逆操作,无法恢复播放器状态
*
* @return Future<void> 异步操作完成标识
* @throws PlatformException 当资源释放失败时抛出异常
*/
Future<void> dispose() async {
final String pigeonVar_channelName =
'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.dispose$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
}