import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_aliplayer/flutter_aliplayer_factory.dart'; import 'package:flutter_aliplayer/flutter_avpdef.dart'; export 'flutter_avpdef.dart'; typedef OnPrepared = void Function(String playerId); typedef OnRenderingStart = void Function(String playerId); typedef OnVideoSizeChanged = void Function( int width, int height, int? rotation, String playerId); typedef OnSnapShot = void Function(String path, String playerId); typedef OnSeekComplete = void Function(String playerId); typedef OnSeiData = void Function(int type, String data, String playerId); typedef OnLoadingBegin = void Function(String playerId); typedef OnLoadingProgress = void Function( int percent, double? netSpeed, String playerId); typedef OnLoadingEnd = void Function(String playerId); typedef OnStateChanged = void Function(int newState, String playerId); typedef OnSubtitleExtAdded = void Function( int trackIndex, String url, String playerId); typedef OnSubtitleShow = void Function( int trackIndex, int subtitleID, String subtitle, String playerId); typedef OnSubtitleHide = void Function( int trackIndex, int subtitleID, String playerId); typedef OnSubtitleHeader = void Function( int trackIndex, String head, String playerId); typedef OnTrackReady = void Function(String playerId); typedef OnInfo = void Function( int? infoCode, int? extraValue, String? extraMsg, String playerId); typedef OnError = void Function( int errorCode, String? errorExtra, String? errorMsg, String playerId); typedef OnCompletion = void Function(String playerId); typedef OnTrackChanged = void Function(dynamic value, String playerId); typedef OnThumbnailPreparedSuccess = void Function(String playerId); typedef OnThumbnailPreparedFail = void Function(String playerId); typedef OnThumbnailGetSuccess = void Function( Uint8List bitmap, Int64List range, String playerId); typedef OnThumbnailGetFail = void Function(String playerId); typedef OnSeekLiveCompletion = void Function(int playTime, String playerId); typedef OnTimeShiftUpdater = void Function( int currentTime, int shiftStartTime, int shiftEndTime, String playerId); typedef OnEventReportParams = void Function(Map params, String playerId); class FlutterAliplayer { OnLoadingBegin? onLoadingBegin; OnLoadingProgress? onLoadingProgress; OnLoadingEnd? onLoadingEnd; OnPrepared? onPrepared; OnRenderingStart? onRenderingStart; OnVideoSizeChanged? onVideoSizeChanged; OnSeekComplete? onSeekComplete; OnStateChanged? onStateChanged; OnInfo? onInfo; OnCompletion? onCompletion; OnTrackReady? onTrackReady; OnError? onError; OnSeiData? onSeiData; OnSnapShot? onSnapShot; OnTrackChanged? onTrackChanged; OnThumbnailPreparedSuccess? onThumbnailPreparedSuccess; OnThumbnailPreparedFail? onThumbnailPreparedFail; OnThumbnailGetSuccess? onThumbnailGetSuccess; OnThumbnailGetFail? onThumbnailGetFail; //外挂字幕 OnSubtitleExtAdded? onSubtitleExtAdded; OnSubtitleHide? onSubtitleHide; OnSubtitleShow? onSubtitleShow; OnSubtitleHeader? onSubtitleHeader; //直播时移 OnSeekLiveCompletion? onSeekLiveCompletion; OnTimeShiftUpdater? onTimeShiftUpdater; //埋点 OnEventReportParams? onEventReportParams; // static MethodChannel channel = new MethodChannel('flutter_aliplayer'); EventChannel eventChannel = EventChannel("flutter_aliplayer_event"); String playerId = 'default'; FlutterAliplayer.init(String? id) { if (id != null) { playerId = id; } FlutterAliPlayerFactory.instanceMap[playerId] = this; register(); } void register() { eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError); } /// 播放器事件回调,准备完成事件 void setOnPrepared(OnPrepared prepared) { this.onPrepared = prepared; } /// 播放器事件回调,首帧显示事件 void setOnRenderingStart(OnRenderingStart renderingStart) { this.onRenderingStart = renderingStart; } /// 视频大小变化回调 void setOnVideoSizeChanged(OnVideoSizeChanged videoSizeChanged) { this.onVideoSizeChanged = videoSizeChanged; } /// 获取截图回调 void setOnSnapShot(OnSnapShot snapShot) { this.onSnapShot = snapShot; } // 播放器事件回调,跳转完成事件 void setOnSeekComplete(OnSeekComplete seekComplete) { this.onSeekComplete = seekComplete; } /// 错误代理回调 void setOnError(OnError onError) { this.onError = onError; } /// SEI回调 void setOnSeiData(OnSeiData seiData) { this.onSeiData = seiData; } /// 视频缓冲相关回调 /// loadingBegin: 播放器事件回调,缓冲开始事件 /// loadingProgress: 视频缓冲进度回调 /// loadingEnd: 播放器事件回调,缓冲完成事件 void setOnLoadingStatusListener( {required OnLoadingBegin loadingBegin, required OnLoadingProgress loadingProgress, required OnLoadingEnd loadingEnd}) { this.onLoadingBegin = loadingBegin; this.onLoadingProgress = loadingProgress; this.onLoadingEnd = loadingEnd; } /// 播放器状态改变回调 void setOnStateChanged(OnStateChanged stateChanged) { this.onStateChanged = stateChanged; } /// 视频当前播放位置回调 void setOnInfo(OnInfo info) { this.onInfo = info; } /// 播放器事件回调,播放完成事件 void setOnCompletion(OnCompletion completion) { this.onCompletion = completion; } /// 获取track信息回调 void setOnTrackReady(OnTrackReady onTrackReady) { this.onTrackReady = onTrackReady; } /// track切换完成回调 void setOnTrackChanged(OnTrackChanged onTrackChanged) { this.onTrackChanged = onTrackChanged; } void setOnThumbnailPreparedListener( {required OnThumbnailPreparedSuccess preparedSuccess, required OnThumbnailPreparedFail preparedFail}) { this.onThumbnailPreparedSuccess = preparedSuccess; this.onThumbnailPreparedFail = preparedFail; } /// 获取缩略图相关回调 /// onThumbnailGetSuccess: 获取缩略图成功回调 /// onThumbnailGetFail: 获取缩略图失败回调 void setOnThumbnailGetListener( {required OnThumbnailGetSuccess onThumbnailGetSuccess, required OnThumbnailGetFail onThumbnailGetFail}) { this.onThumbnailGetSuccess = onThumbnailGetSuccess; this.onThumbnailGetSuccess = onThumbnailGetSuccess; } /// 字幕显示回调 void setOnSubtitleShow(OnSubtitleShow onSubtitleShow) { this.onSubtitleShow = onSubtitleShow; } /// 字幕隐藏回调 void setOnSubtitleHide(OnSubtitleHide onSubtitleHide) { this.onSubtitleHide = onSubtitleHide; } /// 字幕头信息回调 /// ass字幕,如果实现了此回调,则播放器不会渲染字幕,由调用者完成渲染,否则播放器自动完成字幕的渲染 void setOnSubtitleHeader(OnSubtitleHeader onSubtitleHeader) { this.onSubtitleHeader = onSubtitleHeader; } /// 外挂字幕被添加 void setOnSubtitleExtAdded(OnSubtitleExtAdded onSubtitleExtAdded) { this.onSubtitleExtAdded = onSubtitleExtAdded; } void setOnSeekLiveCompletion(OnSeekLiveCompletion seekLiveCompletion) { this.onSeekLiveCompletion = seekLiveCompletion; } void setOnTimeShiftUpdater(OnTimeShiftUpdater timeShiftUpdater) { this.onTimeShiftUpdater = timeShiftUpdater; } /// 埋点事件参数回调 void setOnEventReportParams(OnEventReportParams eventReportParams) { this.onEventReportParams = eventReportParams; } ///接口部分 wrapWithPlayerId({arg = ''}) { var map = {"arg": arg, "playerId": this.playerId.toString()}; return map; } /// 创建播放器 Future create() async { var invokeMethod = FlutterAliPlayerFactory.methodChannel.invokeMethod( 'createAliPlayer', wrapWithPlayerId(arg: PlayerType.PlayerType_Single)); // sendCustomEvent("source=flutter"); return invokeMethod; } /// 设置播放器的视图playerView Future setPlayerView(int viewId) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setPlayerView', wrapWithPlayerId(arg: viewId)); } /// 使用url方式来播放视频 Future setUrl(String url) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setUrl', wrapWithPlayerId(arg: url)); } /// 播放准备 Future prepare() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('prepare', wrapWithPlayerId()); } /// 开始播放 Future play() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('play', wrapWithPlayerId()); } /// 暂停播放 Future pause() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('pause', wrapWithPlayerId()); } /// 清空画面 Future clearScreen() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('clearScreen', wrapWithPlayerId()); } /// 截图 /// 信息可在获取截图回调中取得 Future snapshot(String path) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('snapshot', wrapWithPlayerId(arg: path)); } /// 停止播放 Future stop() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('stop', wrapWithPlayerId()); } /// 销毁播放器 Future destroy() async { FlutterAliPlayerFactory.instanceMap.remove(playerId); return FlutterAliPlayerFactory.methodChannel .invokeMethod('destroy', wrapWithPlayerId()); } /// 跳转到指定的播放位置 Future seekTo(int position, int seekMode) async { var map = {"position": position, "seekMode": seekMode}; return FlutterAliPlayerFactory.methodChannel .invokeMethod("seekTo", wrapWithPlayerId(arg: map)); } /// 设置精准seek的最大间隔 Future setMaxAccurateSeekDelta(int delta) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setMaxAccurateSeekDelta", wrapWithPlayerId(arg: delta)); } /// 当前是否循环播放 Future isLoop() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('isLoop', wrapWithPlayerId()); } /// 设置是否循环播放 Future setLoop(bool isloop) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setLoop', wrapWithPlayerId(arg: isloop)); } /// 当前是否自动播放 Future isAutoPlay() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('isAutoPlay', wrapWithPlayerId()); } /// 设置是否自动播放 Future setAutoPlay(bool isAutoPlay) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setAutoPlay', wrapWithPlayerId(arg: isAutoPlay)); } /// 设置视频快速启动 Future setFastStart(bool fastStart) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setFastStart", wrapWithPlayerId(arg: fastStart)); } /// 当前是否静音 Future isMuted() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('isMuted', wrapWithPlayerId()); } /// 设置是否静音 Future setMuted(bool isMuted) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setMuted', wrapWithPlayerId(arg: isMuted)); } /// 当前是否开启硬件解码 Future enableHardwareDecoder() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('enableHardwareDecoder', wrapWithPlayerId()); } /// 设置是否开启硬件解码 Future setEnableHardwareDecoder(bool isHardWare) async { return FlutterAliPlayerFactory.methodChannel.invokeMethod( 'setEnableHardwareDecoder', wrapWithPlayerId(arg: isHardWare)); } /// 用vid和sts来播放视频 /// sts可参考:https://help.aliyun.com/document_detail/28756.html?spm=a2c4g.11186623.4.4.6f554c07q7B7aS /// playConfig 从[generatePlayerConfig]获取 Future setVidSts( {String? vid, String? region, String? accessKeyId, String? accessKeySecret, String? securityToken, String? playConfig, List? definitionList, String quality = "", bool forceQuality = false, playerId}) async { Map stsInfo = { "vid": vid, "region": region, "accessKeyId": accessKeyId, "accessKeySecret": accessKeySecret, "securityToken": securityToken, "definitionList": definitionList, "playConfig": playConfig, "quality": quality, "forceQuality": forceQuality }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("setVidSts", wrapWithPlayerId(arg: stsInfo)); } /// 使用vid+playauth方式播放 /// 可参考:https://help.aliyun.com/document_detail/57294.html /// playConfig 从[generatePlayerConfig]获取 Future setVidAuth( {String? vid, String? region, String? playAuth, String? playConfig, List? definitionList, String quality = "", bool forceQuality = false, playerId}) async { Map authInfo = { "vid": vid, "region": region, "playAuth": playAuth, "definitionList": definitionList, "playConfig": playConfig, "quality": quality, "forceQuality": forceQuality }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("setVidAuth", wrapWithPlayerId(arg: authInfo)); } /// 用vid和MPS信息来播放视频 /// 可参考:https://help.aliyun.com/document_detail/53522.html?spm=5176.doc53534.2.5.mhSfOh Future setVidMps(Map mpsInfo) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setVidMps", wrapWithPlayerId(arg: mpsInfo)); } /// 使用LiveSts 方式播放直播流 Future setLiveSts( {String? url, String? accessKeyId, String? accessKeySecret, String? securityToken, String? region, String? domain, String? app, String? stream, EncryptionType? encryptionType, List? definitionList, playerId}) async { Map liveStsInfo = { "url": url, "accessKeyId": accessKeyId, "accessKeySecret": accessKeySecret, "securityToken": securityToken, "region": region, "domain": domain, "app": app, "stream": stream, "encryptionType": encryptionType?.index.toString(), "definitionList": definitionList, }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("setLiveSts", wrapWithPlayerId(arg: liveStsInfo)); } /// 更新LiveSts信息 Future updateLiveStsInfo( String accId, String accKey, String token, String region) async { Map liveStsInfo = { "accId": accId, "accKey": accKey, "token": token, "region": region, }; return FlutterAliPlayerFactory.methodChannel .invokeMethod('updateLiveStsInfo', wrapWithPlayerId(arg: liveStsInfo)); } /// 获取渲染旋转模式 Future getRotateMode() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getRotateMode', wrapWithPlayerId()); } /// 设置渲染旋转模式 Future setRotateMode(int mode) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setRotateMode', wrapWithPlayerId(arg: mode)); } /// 获取渲染填充模式 Future getScalingMode() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getScalingMode', wrapWithPlayerId()); } /// 设置渲染填充模式 Future setScalingMode(int mode) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setScalingMode', wrapWithPlayerId(arg: mode)); } /// 获取渲染镜像模式 Future getMirrorMode() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getMirrorMode', wrapWithPlayerId()); } /// 设置渲染镜像模式 Future setMirrorMode(int mode) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setMirrorMode', wrapWithPlayerId(arg: mode)); } /// 获取播放速率 Future getRate() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getRate', wrapWithPlayerId()); } /// 设置播放速率 /// 0.5-2.0之间,1为正常播放 Future setRate(double mode) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setRate', wrapWithPlayerId(arg: mode)); } /// 设置视频的背景色 Future setVideoBackgroundColor(var color) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setVideoBackgroundColor', wrapWithPlayerId(arg: color)); } /// 获取视频的宽度 Future getVideoWidth() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getVideoWidth', wrapWithPlayerId()); } /// 获取视频的高度 Future getVideoHeight() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getVideoHeight', wrapWithPlayerId()); } /// 获取视频的旋转角度 Future getVideoRotation() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getVideoRotation', wrapWithPlayerId()); } /// 设置播放器的音量(非系统音量) /// 范围0.0~2.0,当音量大于1.0时,可能出现噪音,不推荐使用 Future setVolume(double volume) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('setVolume', wrapWithPlayerId(arg: volume)); } /// 获取播放器的音量(非系统音量) Future getVolume() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getVolume', wrapWithPlayerId()); } /// 获取视频的长度 Future getDuration() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getDuration', wrapWithPlayerId()); } /// 获取当前播放位置 Future getCurrentPosition() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getCurrentPosition', wrapWithPlayerId()); } /// 获取当前播放位置的utc时间 Future getCurrentUtcTime() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getCurrentUtcTime', wrapWithPlayerId()); } /// 获取当前播放命中的缓存文件大小 Future getLocalCacheLoadedSize() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getLocalCacheLoadedSize', wrapWithPlayerId()); } /// 获取当前下载速度 Future getCurrentDownloadSpeed() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getCurrentDownloadSpeed', wrapWithPlayerId()); } /// 获取已经缓存的位置 Future getBufferedPosition() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('getBufferedPosition', wrapWithPlayerId()); } /// 获取播放器设置 Future getConfig() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("getConfig", wrapWithPlayerId()); } /// 获取播放器设置 /// 新版本增加,逐步替代[getConfig] Future getPlayConfig() async { Map map = await FlutterAliPlayerFactory.methodChannel .invokeMethod("getPlayConfig", wrapWithPlayerId()); return AVPConfig.convertAt(map); } /// 播放器设置,传递map Future setConfig(Map map) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setConfig", wrapWithPlayerId(arg: map)); } /// 播放器设置 /// 新版本增加,逐步替代[setConfig] Future setPlayConfig(AVPConfig config) async { Map map = config.convertToMap(); return FlutterAliPlayerFactory.methodChannel .invokeMethod("setPlayConfig", wrapWithPlayerId(arg: map)); } /// 播放器降级设置 /// source 降级url /// config 降级配置 Future enableDowngrade(String source, AVPConfig config) async { Map map = { "source": source, "config": config.convertToMap(), }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("enableDowngrade", wrapWithPlayerId(arg: map)); } Future getCacheConfig() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("getCacheConfig", wrapWithPlayerId()); } /// 设置缓存配置 Future setCacheConfig(Map map) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setCacheConfig", wrapWithPlayerId(arg: map)); } /// 设置滤镜配置 /// 在prepare之前调用此方法。如果想更新,调用updateFilterConfig Future setFilterConfig(String configJson) async { // configJson格式: "[{"target":"", "options":[""]}, {"target":"", "options":},...]" // options_key 目前有两种"sharp"、"sr" return FlutterAliPlayerFactory.methodChannel .invokeMethod("setFilterConfig", wrapWithPlayerId(arg: configJson)); } /// 更新滤镜配置 Future updateFilterConfig(String target, Map options) async { var map = {'target': target, 'options': options}; // options格式: {"key":"", "value": ""} return FlutterAliPlayerFactory.methodChannel .invokeMethod("updateFilterConfig", wrapWithPlayerId(arg: map)); } /// 开启关闭滤镜 Future setFilterInvalid(String target, String invalid) async { var map = {'target': target, 'invalid': invalid}; return FlutterAliPlayerFactory.methodChannel .invokeMethod("setFilterInvalid", wrapWithPlayerId(arg: map)); } /// 根据url获取缓存的文件名 Future getCacheFilePath(String url) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("getCacheFilePath", wrapWithPlayerId(arg: url)); } /// 根据vid获取缓存的文件名 Future getCacheFilePathWithVid( String vid, String format, String definition) async { var map = {'vid': vid, 'format': format, 'definition': definition}; return FlutterAliPlayerFactory.methodChannel .invokeMethod("getCacheFilePathWithVid", wrapWithPlayerId(arg: map)); } /// 根据vid+试看时长获取缓存的文件名 Future getCacheFilePathWithVidAtPreviewTime( String vid, String format, String definition, String previewTime) async { var map = { 'vid': vid, 'format': format, 'definition': definition, 'previewTime': previewTime }; return FlutterAliPlayerFactory.methodChannel.invokeMethod( "getCacheFilePathWithVidAtPreviewTime", wrapWithPlayerId(arg: map)); } /// 获取媒体信息,包括track信息 Future getMediaInfo() { return FlutterAliPlayerFactory.methodChannel .invokeMethod("getMediaInfo", wrapWithPlayerId()); } /// 获取当前播放track Future getCurrentTrack(int trackIdx) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("getCurrentTrack", wrapWithPlayerId(arg: trackIdx)); } /// 设置缩略图URL Future createThumbnailHelper(String thumbnail) { return FlutterAliPlayerFactory.methodChannel.invokeMethod( "createThumbnailHelper", wrapWithPlayerId(arg: thumbnail)); } /// 获取指定位置的缩略图 Future requestBitmapAtPosition(int position) { return FlutterAliPlayerFactory.methodChannel.invokeMethod( "requestBitmapAtPosition", wrapWithPlayerId(arg: position)); } /// 设置traceID,用于跟踪debug信息 /// 通过埋点事件回调onEventReportParams Future setTraceID(String traceID) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setTraceID", wrapWithPlayerId(arg: traceID)); } /// 添加外挂字幕 Future addExtSubtitle(String url) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("addExtSubtitle", wrapWithPlayerId(arg: url)); } /// 选择外挂字幕 Future selectExtSubtitle(int trackIndex, bool enable) { var map = {'trackIndex': trackIndex, 'enable': enable}; return FlutterAliPlayerFactory.methodChannel .invokeMethod("selectExtSubtitle", wrapWithPlayerId(arg: map)); } /// 设置多码率时默认播放的码率 /// 将会选择与之最接近的一路流播放 Future setDefaultBandWidth(int parse) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setDefaultBandWidth", wrapWithPlayerId(arg: parse)); } /// 根据trackIndex,切换清晰度 /// trackIdx 选择清晰度的index,-1代表自适应码率 /// accurate 0 为不精确 1 为精确 不填为忽略 Future selectTrack( int trackIdx, { int accurate = -1, }) { var map = { 'trackIdx': trackIdx, 'accurate': accurate, }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("selectTrack", wrapWithPlayerId(arg: map)); } Future setPrivateService(Int8List data) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setPrivateService", data); } /// 设置期望使用的播放器名字 Future setPreferPlayerName(String playerName) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setPreferPlayerName", wrapWithPlayerId(arg: playerName)); } /// 获取播放时使用的播放器名字 Future getPlayerName() { return FlutterAliPlayerFactory.methodChannel .invokeMethod("getPlayerName", wrapWithPlayerId()); } /// 发送用户自定义事件 /// 通过埋点事件回调onEventReportParams Future sendCustomEvent(String args) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("sendCustomEvent", wrapWithPlayerId(arg: args)); } /// 设置UserData,用于一些全局API的透传,以区分player实例。 Future setUserData(String userData) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setUserData", wrapWithPlayerId(arg: userData)); } /// 设置UserData,用于一些全局API的透传,以区分player实例。 Future getUserData() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("getUserData", wrapWithPlayerId()); } /// 设置某路流相对于主时钟的延时时间 /// 默认是0, 目前只支持外挂字幕 Future setStreamDelayTime(int trackIdx, int time) { var map = {'index': trackIdx, 'time': time}; return FlutterAliPlayerFactory.methodChannel .invokeMethod("setStreamDelayTime", wrapWithPlayerId(arg: map)); } /// 重新加载 /// 比如网络超时时,可以重新加载。 Future reload() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod('reload', wrapWithPlayerId()); } /// 获取播放器的参数 Future getOption(AVPOption key) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("getOption", wrapWithPlayerId(arg: key.index.toString())); } /// 根据key获取相应的信息 Future getPropertyString(AVPPropertyKey key) { return FlutterAliPlayerFactory.methodChannel.invokeMethod( "getPropertyString", wrapWithPlayerId(arg: key.index.toString())); } /// 设置埋点事件回调onEventReportParams代理 Future setEventReportParamsDelegate(int argt) { return FlutterAliPlayerFactory.methodChannel.invokeMethod( "setEventReportParamsDelegate", wrapWithPlayerId(arg: argt.toString())); } /// 设置画中画功能开启/关闭 /// 仅对iOS系统有效,在iOS 15以上系统应用 /// 需要在onPrepared回调方法中调用 Future setPictureInPictureEnableForIOS(bool enable) { return FlutterAliPlayerFactory.methodChannel.invokeMethod( "setPictureInPictureEnableForIOS", wrapWithPlayerId(arg: enable.toString())); } ///静态方法 /// 获取SDK版本号信息 static Future getSDKVersion() async { return FlutterAliPlayerFactory.methodChannel.invokeMethod("getSDKVersion"); } /// 获取设备UUID static Future getDeviceUUID() async { return FlutterAliPlayerFactory.methodChannel.invokeMethod("getDeviceUUID"); } /// 返回某项功能是否支持 /// type 是否支持的功能的类型。 参考SupportFeatureType。 static Future isFeatureSupport(SupportFeatureType type) async { bool boolV = await FlutterAliPlayerFactory.methodChannel .invokeMethod("isFeatureSupport", type.index); return boolV; } /// 控制音频设置 /// 默认按照播放器SDK自身设置,只对iOS平台有效 /// 替代旧版本的[enableMix] static Future setAudioSessionTypeForIOS( AliPlayerAudioSesstionType type) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setAudioSessionTypeForIOS", type.index); } /// 是否打开log输出 static Future enableConsoleLog(bool enable) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("enableConsoleLog", enable); } /// 设置日志打印回调block /// logLevel log输出级别 static Future setLogLevel(int level) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setLogLevel", level); } /// 获取日志级别 /// 仅对Android系统有效 static Future getLogLevel() { return FlutterAliPlayerFactory.methodChannel.invokeMethod( "getLogLevel", ); } /// 设置是否使用http2 static Future setUseHttp2(bool use) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setUseHttp2", use); } /// 是否开启httpDNS /// 默认不开启 static Future enableHttpDns(bool enable) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("enableHttpDns", enable); } /// 设置域名对应的解析ip /// host 域名,需指定端口(http默认端口80,https默认端口443)。例如player.alicdn.com:443 /// ip 相应的ip,设置为空字符串清空设定。 static Future setDNSResolve(String host, String ip) { Map map = { "host": host, "ip": ip, }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("setDNSResolve", map); } /// 设置解析ip类型 static Future setIpResolveType(AVPIpResolveType type) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setIpResolveType", type.index.toString()); } /// 设置fairPlay的用户证书id /// 仅对iOS系统有效 static Future setFairPlayCertIDForIOS(String certID) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setFairPlayCertIDForIOS", certID); } /// 设置是否使能硬件提供的音频变速播放能力 /// 关闭后则使用软件实现音频的倍速播放,pcm回调数据的格式和此设置关联;默认打开 static Future enableHWAduioTempo(bool enable) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("enableHWAduioTempo", enable); } /// 强制音频渲染器采用指定的格式进行渲染 /// 如果设定的格式设备不支持,则无效,无效值将被忽略,使用默认值;pcm回调数据的格式和此设置关联;默认关闭 static Future forceAudioRendingFormat( String force, String fmt, String channels, String sample_rate) { var map = { 'force': force, 'fmt': fmt, 'channels': channels, 'sample_rate': sample_rate }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("forceAudioRendingFormat", map); } /// 重连所有网络连接 /// 网络路由发生变化后,调用此接口,可以让播放器所有的连接切换到新的路由上去。 static Future netWorkReConnect() { return FlutterAliPlayerFactory.methodChannel .invokeMethod("netWorkReConnect"); } /// 开启本地缓存 /// 开启之后,就会缓存到本地文件中。 static Future enableLocalCache(bool enable, String maxBufferMemoryKB, String localCacheDir, DocTypeForIOS docTypeForIOS) { var map = { 'enable': enable, 'maxBufferMemoryKB': maxBufferMemoryKB, 'localCacheDir': localCacheDir, }; if (Platform.isIOS) { // docTypeForIOS的取值代表沙盒目录路径类型 "0":Documents, "1":Library, "2":Caches, 其他:Documents map['docTypeForIOS'] = docTypeForIOS.index.toString(); } else { // 安卓不需设置docType,直接传递localCacheDir } return FlutterAliPlayerFactory.methodChannel .invokeMethod("enableLocalCache", map); } /// 本地缓存文件自动清理相关的设置 static Future setCacheFileClearConfig( String expireMin, String maxCapacityMB, String freeStorageMB) { var map = { 'expireMin': expireMin, 'maxCapacityMB': maxCapacityMB, 'freeStorageMB': freeStorageMB, }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("setCacheFileClearConfig", map); } /// 是否开启内建预加载网络平衡策略,播放过程中,自动控制预加载的运行时机。默认开启。 /// enable 是否开启 static Future enableNetworkBalance(bool enable) { return FlutterAliPlayerFactory.methodChannel .invokeMethod("enableNetworkBalance", enable); } /// 清理本地缓存,需要先应用配置缓存,才能清理本地缓存 static Future clearCaches() { return FlutterAliPlayerFactory.methodChannel.invokeMethod("clearCaches"); } ///return deviceInfo static Future createDeviceInfo() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("createDeviceInfo"); } ///type : {FlutterAvpdef.BLACK_DEVICES_H264 / FlutterAvpdef.BLACK_DEVICES_HEVC} static Future addBlackDevice(String type, String model) async { var map = { 'black_type': type, 'black_device': model, }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("addBlackDevice", map); } /// 创建媒体播放自定义设置对象 static Future createVidPlayerConfigGenerator() async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("createVidPlayerConfigGenerator"); } /// 设置预览时间 /// previewTime 预览时间,单位为秒 /// 调用之前必须先执行[createVidPlayerConfigGenerator] static Future setPreviewTime(int previewTime) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setPreviewTime", previewTime.toString()); } /// HLS标准加密设置UriToken /// mtsHlsUriToken 字符串 /// 调用之前必须先执行[createVidPlayerConfigGenerator] static Future setHlsUriToken(String mtsHlsUriToken) async { return FlutterAliPlayerFactory.methodChannel .invokeMethod("setHlsUriToken", mtsHlsUriToken); } /// 添加vid的playerconfig参数 /// key: 对应playerConfig中的参数名字 /// value: 对应key参数的值 /// 调用之前必须先执行[createVidPlayerConfigGenerator] /// Android 设置加密类型:key 为 EncryptType,value 可选:Unencrypted,AliyunVoDEncryption,HLSEncryption static Future addVidPlayerConfigByStringValue( String key, String value) async { Map param = { "key": key, "value": value, }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("addVidPlayerConfigByStringValue", param); } /// 添加vid的playerconfig参数 /// key: 对应playerConfig中的参数名字 /// value: 对应key参数的整形值 /// 调用之前必须先执行[createVidPlayerConfigGenerator] static Future addVidPlayerConfigByIntValue( String key, int value) async { Map param = { "key": key, "value": value.toString(), }; return FlutterAliPlayerFactory.methodChannel .invokeMethod("addVidPlayerConfigByIntValue", param); } /// 生成playerConfig /// 调用之前必须先执行[createVidPlayerConfigGenerator] static Future generatePlayerConfig() async { return await FlutterAliPlayerFactory.methodChannel .invokeMethod("generatePlayerConfig"); } ///回调分发 void _onEvent(dynamic event) { String method = event[EventChanneldef.TYPE_KEY]; String playerId = event['playerId'] ?? ''; FlutterAliplayer player = FlutterAliPlayerFactory.instanceMap[playerId] ?? this; switch (method) { case "onPrepared": if (player.onPrepared != null) { player.onPrepared!(playerId); } break; case "onRenderingStart": if (player.onRenderingStart != null) { player.onRenderingStart!(playerId); } break; case "onVideoSizeChanged": if (player.onVideoSizeChanged != null) { int width = event['width']; int height = event['height']; int? rotation = event['rotation']; player.onVideoSizeChanged!(width, height, rotation, playerId); } break; case "onSnapShot": if (player.onSnapShot != null) { String snapShotPath = event['snapShotPath']; player.onSnapShot!(snapShotPath, playerId); } break; case "onChangedSuccess": break; case "onChangedFail": break; case "onSeekComplete": if (player.onSeekComplete != null) { player.onSeekComplete!(playerId); } break; case "onSeiData": if (player.onSeiData != null) { String data = event['data']; int type = event['type']; player.onSeiData!(type, data, playerId); } break; case "onLoadingBegin": if (player.onLoadingBegin != null) { player.onLoadingBegin!(playerId); } break; case "onLoadingProgress": int percent = event['percent']; double? netSpeed = event['netSpeed']; if (player.onLoadingProgress != null) { player.onLoadingProgress!(percent, netSpeed, playerId); } break; case "onLoadingEnd": if (player.onLoadingEnd != null) { player.onLoadingEnd!(playerId); } break; case "onStateChanged": if (player.onStateChanged != null) { int newState = event['newState']; player.onStateChanged!(newState, playerId); } break; case "onInfo": if (player.onInfo != null) { int? infoCode = event['infoCode']; int? extraValue = event['extraValue']; String? extraMsg = event['extraMsg']; player.onInfo!(infoCode, extraValue, extraMsg, playerId); } break; case "onError": if (player.onError != null) { int errorCode = event['errorCode']; String? errorExtra = event['errorExtra']; String? errorMsg = event['errorMsg']; player.onError!(errorCode, errorExtra, errorMsg, playerId); } break; case "onCompletion": if (player.onCompletion != null) { player.onCompletion!(playerId); } break; case "onTrackReady": if (player.onTrackReady != null) { player.onTrackReady!(playerId); } break; case "onTrackChanged": if (player.onTrackChanged != null) { dynamic info = event['info']; player.onTrackChanged!(info, playerId); } break; case "thumbnail_onPrepared_Success": if (player.onThumbnailPreparedSuccess != null) { player.onThumbnailPreparedSuccess!(playerId); } break; case "thumbnail_onPrepared_Fail": if (player.onThumbnailPreparedFail != null) { player.onThumbnailPreparedFail!(playerId); } break; case "onThumbnailGetSuccess": dynamic bitmap = event['thumbnailbitmap']; dynamic range = event['thumbnailRange']; if (player.onThumbnailGetSuccess != null) { if (Platform.isIOS) { range = Int64List.fromList(range.cast()); } player.onThumbnailGetSuccess!(bitmap, range, playerId); } break; case "onThumbnailGetFail": if (player.onThumbnailGetFail != null) { player.onThumbnailGetFail!(playerId); } break; case "onSubtitleExtAdded": if (player.onSubtitleExtAdded != null) { int trackIndex = event['trackIndex']; String url = event['url']; player.onSubtitleExtAdded!(trackIndex, url, playerId); } break; case "onSubtitleShow": if (player.onSubtitleShow != null) { int trackIndex = event['trackIndex']; int subtitleID = event['subtitleID']; String subtitle = event['subtitle']; player.onSubtitleShow!(trackIndex, subtitleID, subtitle, playerId); } break; case "onSubtitleHide": if (player.onSubtitleHide != null) { int trackIndex = event['trackIndex']; int subtitleID = event['subtitleID']; player.onSubtitleHide!(trackIndex, subtitleID, playerId); } break; case "onSubtitleHeader": if (player.onSubtitleHeader != null) { int trackIndex = event['trackIndex']; String header = event['header']; player.onSubtitleHeader!(trackIndex, header, playerId); } break; case "onUpdater": if (player.onTimeShiftUpdater != null) { var currentTime = event['currentTime']; var shiftStartTime = event['shiftStartTime']; var shiftEndTime = event['shiftEndTime']; player.onTimeShiftUpdater!( currentTime, shiftStartTime, shiftEndTime, playerId); } break; case "onSeekLiveCompletion": if (player.onSeekLiveCompletion != null) { var playTime = event['playTime']; player.onSeekLiveCompletion!(playTime, playerId); } break; case "onEventReportParams": if (player.onEventReportParams != null) { var params = event['params']; player.onEventReportParams!(params, playerId); } } } void _onError(dynamic error) {} } typedef void AliPlayerViewCreatedCallback(int viewId); class AliPlayerView extends StatefulWidget { final AliPlayerViewCreatedCallback? onCreated; final x; final y; final width; final height; AliPlayerViewTypeForAndroid aliPlayerViewType; AliPlayerView({ Key? key, @required required this.onCreated, @required this.x, @required this.y, @required this.width, @required this.height, this.aliPlayerViewType = AliPlayerViewTypeForAndroid.surfaceview, }); @override State createState() => _VideoPlayerState(); } class _VideoPlayerState extends State { @override Widget build(BuildContext context) { return nativeView(); } nativeView() { if (Platform.isAndroid) { return AndroidView( viewType: 'flutter_aliplayer_render_view', onPlatformViewCreated: _onPlatformViewCreated, creationParams: { "x": widget.x, "y": widget.y, "width": widget.width, "height": widget.height, "viewType": widget.aliPlayerViewType.name, }, creationParamsCodec: const StandardMessageCodec(), ); } else { return UiKitView( viewType: 'plugins.flutter_aliplayer', // viewType: 'flutter_aliplayer_render_view', onPlatformViewCreated: _onPlatformViewCreated, creationParams: { "x": widget.x, "y": widget.y, "width": widget.width, "height": widget.height, }, creationParamsCodec: const StandardMessageCodec(), ); } } Future _onPlatformViewCreated(id) async { if (widget.onCreated != null) { widget.onCreated!(id); } } }