提交 d5d1f564 authored 作者: kongdywang's avatar kongdywang

fix download error & fix ios pip open failed % fix other known issue

上级 cfcbcc6a
...@@ -144,6 +144,25 @@ public class FTXDownloadManager implements MethodChannel.MethodCallHandler, ITXV ...@@ -144,6 +144,25 @@ public class FTXDownloadManager implements MethodChannel.MethodCallHandler, ITXV
deleteResult = TXVodDownloadManager.getInstance().deleteDownloadMediaInfo(mediaInfo); deleteResult = TXVodDownloadManager.getInstance().deleteDownloadMediaInfo(mediaInfo);
} }
result.success(deleteResult); result.success(deleteResult);
} else if (call.method.equals("resumeDownload")) {
Integer quality = call.argument("quality");
String videoUrl = call.argument("url");
Integer appId = call.argument("appId");
String fileId = call.argument("fileId");
String pSign = call.argument("pSign");
String userName = call.argument("userName");
TXVodDownloadMediaInfo mediaInfo = parseMediaInfoFromInfo(quality, videoUrl, appId, fileId, userName);
boolean resumeResult = false;
if (null != mediaInfo) {
TXVodDownloadDataSource dataSource = mediaInfo.getDataSource();
if (dataSource != null) {
TXVodDownloadManager.getInstance().startDownload(dataSource);
} else {
TXVodDownloadManager.getInstance().startDownloadUrl(mediaInfo.getUrl(), mediaInfo.getUserName());
}
resumeResult = true;
}
result.success(resumeResult);
} }
} }
......
...@@ -6,6 +6,7 @@ import android.graphics.Bitmap; ...@@ -6,6 +6,7 @@ import android.graphics.Bitmap;
import android.graphics.SurfaceTexture; import android.graphics.SurfaceTexture;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.Surface; import android.view.Surface;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.tencent.rtmp.ITXVodPlayListener; import com.tencent.rtmp.ITXVodPlayListener;
...@@ -34,6 +35,8 @@ import java.util.Map; ...@@ -34,6 +35,8 @@ import java.util.Map;
*/ */
public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodCallHandler, ITXVodPlayListener { public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodCallHandler, ITXVodPlayListener {
private static final String TAG = "FTXVodPlayer";
private FlutterPlugin.FlutterPluginBinding mFlutterPluginBinding; private FlutterPlugin.FlutterPluginBinding mFlutterPluginBinding;
private final MethodChannel mMethodChannel; private final MethodChannel mMethodChannel;
...@@ -143,6 +146,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -143,6 +146,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
mMethodChannel.setMethodCallHandler(null); mMethodChannel.setMethodCallHandler(null);
mEventChannel.setStreamHandler(null); mEventChannel.setStreamHandler(null);
mNetChannel.setStreamHandler(null); mNetChannel.setStreamHandler(null);
releaseTXImageSprite();
if (null != mPipManager) { if (null != mPipManager) {
mPipManager.releaseCallback(getPlayerId()); mPipManager.releaseCallback(getPlayerId());
} }
...@@ -352,10 +356,20 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -352,10 +356,20 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
} else if (call.method.equals("initImageSprite")) { } else if (call.method.equals("initImageSprite")) {
String vvtUrl = call.argument("vvtUrl"); String vvtUrl = call.argument("vvtUrl");
List<String> imageUrls = call.argument("imageUrls"); List<String> imageUrls = call.argument("imageUrls");
mTxImageSprite.setVTTUrlAndImageUrls(vvtUrl,imageUrls); releaseTXImageSprite();
mTxImageSprite = new TXImageSprite(mFlutterPluginBinding.getApplicationContext());
mTxImageSprite.setVTTUrlAndImageUrls(vvtUrl, imageUrls);
result.success(null); result.success(null);
} else if (call.method.equals("getImageSprite")) { } else if (call.method.equals("getImageSprite")) {
final Double time = call.argument("time"); final Double time = call.argument("time");
getImageSprite(time, result);
} else {
result.notImplemented();
}
}
private void getImageSprite(final Double time, final MethodChannel.Result result) {
if (mTxImageSprite != null && null != time) {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
...@@ -371,7 +385,15 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -371,7 +385,15 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
} }
}).start(); }).start();
} else { } else {
result.notImplemented(); Log.e(TAG, "getImageSprite failed, time is null or initImageSprite not invoke");
result.success(null);
}
}
private void releaseTXImageSprite() {
if (mTxImageSprite != null) {
mTxImageSprite.release();
mTxImageSprite = null;
} }
} }
...@@ -380,7 +402,6 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -380,7 +402,6 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
mVodPlayer = new TXVodPlayer(mFlutterPluginBinding.getApplicationContext()); mVodPlayer = new TXVodPlayer(mFlutterPluginBinding.getApplicationContext());
mVodPlayer.setVodListener(this); mVodPlayer.setVodListener(this);
setPlayer(onlyAudio); setPlayer(onlyAudio);
mTxImageSprite = new TXImageSprite(mFlutterPluginBinding.getApplicationContext());
} }
return mSurfaceTextureEntry == null ? -1 : mSurfaceTextureEntry.id(); return mSurfaceTextureEntry == null ? -1 : mSurfaceTextureEntry.id();
} }
...@@ -427,6 +448,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -427,6 +448,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
if (mVodPlayer != null) { if (mVodPlayer != null) {
return mVodPlayer.stopPlay(isNeedClearLastImg); return mVodPlayer.stopPlay(isNeedClearLastImg);
} }
releaseTXImageSprite();
mHardwareDecodeFail = false; mHardwareDecodeFail = false;
return Uninitialized; return Uninitialized;
} }
......
...@@ -225,6 +225,28 @@ uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library ...@@ -225,6 +225,28 @@ uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library
static const LOG_LEVEL_NULL = 6; // 不输出任何sdk log static const LOG_LEVEL_NULL = 6; // 不输出任何sdk log
} }
``` ```
9. 项目使用过程中,出现原生相关报错,例如`错误: 不兼容的类型`、`error: initializing 'BOOL' (aka 'bool') with an expression of incompatible type 'void'`等错误,是由于SDK更新,导致SDK与flutter端原生代码不兼容。此时只需要更新SDK版本即可。
**解决方法**:在项目目录下,打开终端,依次输入如下命令
```shell
flutter pub cache clean
flutter clean
flutter pub upgrade
flutter pub get
```
确保命令执行成功,更新本地flutter依赖。
然后在ios目录下,打开终端,输入如下命令,更新IOS依赖
```shell
rm -rf Pods
rm -rf Podfile.lock
pod update
```
如果问题依然存在,可以尝试删除项目build文件夹,并且手动删除你电脑中的flutter依赖缓存文件夹`.pubcache`。然后重新刷新flutter pub依赖再进行编译运行。
## 更多功能 ## 更多功能
......
...@@ -32,10 +32,11 @@ class _DemoDownloadListState extends State<StatefulWidget> { ...@@ -32,10 +32,11 @@ class _DemoDownloadListState extends State<StatefulWidget> {
void registerListener() { void registerListener() {
DownloadHelper.instance.addDownloadListener(listener = FTXDownloadListener((event, info) { DownloadHelper.instance.addDownloadListener(listener = FTXDownloadListener((event, info) {
List<DownloadModel> tempModels = models; List<DownloadModel> tempModels = models;
for (DownloadModel downloadModel in tempModels) { for (int i = 0; i < models.length; i++) {
DownloadModel downloadModel = models[i];
if (_compareMediaInfo(downloadModel.mediaInfo, info)) { if (_compareMediaInfo(downloadModel.mediaInfo, info)) {
tempModels.remove(downloadModel); tempModels.removeAt(i);
tempModels.add(DownloadModel(downloadModel.videoModel, info)); tempModels.insert(i, DownloadModel(downloadModel.videoModel, info));
} }
} }
setState(() { setState(() {
...@@ -43,10 +44,11 @@ class _DemoDownloadListState extends State<StatefulWidget> { ...@@ -43,10 +44,11 @@ class _DemoDownloadListState extends State<StatefulWidget> {
}); });
}, (errorCode, errorMsg, info) { }, (errorCode, errorMsg, info) {
List<DownloadModel> tempModels = models; List<DownloadModel> tempModels = models;
for (DownloadModel downloadModel in tempModels) { for (int i = 0; i < models.length; i++) {
DownloadModel downloadModel = models[i];
if (_compareMediaInfo(downloadModel.mediaInfo, info)) { if (_compareMediaInfo(downloadModel.mediaInfo, info)) {
tempModels.remove(downloadModel); tempModels.removeAt(i);
tempModels.add(DownloadModel(downloadModel.videoModel, info)); tempModels.insert(i, DownloadModel(downloadModel.videoModel, info));
} }
} }
setState(() { setState(() {
...@@ -147,8 +149,8 @@ class _DemoDownloadListState extends State<StatefulWidget> { ...@@ -147,8 +149,8 @@ class _DemoDownloadListState extends State<StatefulWidget> {
SuperPlayerModel playModel = downloadModel.videoModel; SuperPlayerModel playModel = downloadModel.videoModel;
TXVodDownloadMediaInfo mediaInfo = downloadModel.mediaInfo; TXVodDownloadMediaInfo mediaInfo = downloadModel.mediaInfo;
int duration = 0; int duration = 0;
if (mediaInfo.duration != null) { if (mediaInfo.duration != null && mediaInfo.duration != 0) {
if(Platform.isIOS) { if (Platform.isIOS) {
duration = mediaInfo.duration!; duration = mediaInfo.duration!;
} else { } else {
duration = mediaInfo.duration! ~/ 1000; duration = mediaInfo.duration! ~/ 1000;
...@@ -247,7 +249,7 @@ class _DemoDownloadListState extends State<StatefulWidget> { ...@@ -247,7 +249,7 @@ class _DemoDownloadListState extends State<StatefulWidget> {
stateText = AppLocalizations.of(context).playerCacheError; stateText = AppLocalizations.of(context).playerCacheError;
} else if (mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_STOP) { } else if (mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_STOP) {
stateColor = ColorResource.COLOR_DOWNLOAD_COMPELETE; stateColor = ColorResource.COLOR_DOWNLOAD_COMPELETE;
stateText = AppLocalizations.of(context).playerCacheError; stateText = AppLocalizations.of(context).playerCacheInterrupt;
} else if (mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_FINISH) { } else if (mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_FINISH) {
stateColor = ColorResource.COLOR_DOWNLOAD_COMPELETE; stateColor = ColorResource.COLOR_DOWNLOAD_COMPELETE;
stateText = AppLocalizations.of(context).playerCacheComplete; stateText = AppLocalizations.of(context).playerCacheComplete;
...@@ -304,10 +306,12 @@ class _DemoDownloadListState extends State<StatefulWidget> { ...@@ -304,10 +306,12 @@ class _DemoDownloadListState extends State<StatefulWidget> {
playerModel.videoURL = downloadModel.mediaInfo.playPath!; playerModel.videoURL = downloadModel.mediaInfo.playPath!;
// 置空videoId,避免播放器组件对url进行额外的参数拼接 // 置空videoId,避免播放器组件对url进行额外的参数拼接
playerModel.videoId = null; playerModel.videoId = null;
// 置空multiVideoURLs,避免播放器组件有限对多码率url进行播放
playerModel.multiVideoURLs = [];
Navigator.of(context).pop(playerModel); Navigator.of(context).pop(playerModel);
} else if (mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_STOP || } else if (mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_STOP ||
mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_ERROR) { mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_ERROR) {
DownloadHelper.instance.startDownloadOrg(downloadModel.mediaInfo); DownloadHelper.instance.resumeDownloadOrg(downloadModel.mediaInfo);
refreshDownloadList(); refreshDownloadList();
} else if (mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_PROGRESS || } else if (mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_PROGRESS ||
mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_START) { mediaInfo.downloadState == TXVodPlayEvent.EVENT_DOWNLOAD_START) {
......
...@@ -20,6 +20,7 @@ class DemoSuperPlayer extends StatefulWidget { ...@@ -20,6 +20,7 @@ class DemoSuperPlayer extends StatefulWidget {
} }
class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerRestorePage { class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerRestorePage {
static const TAG = "_DemoSuperPlayerState";
static const DEFAULT_PLACE_HOLDER = "http://xiaozhibo-10055601.file.myqcloud.com/coverImg.jpg"; static const DEFAULT_PLACE_HOLDER = "http://xiaozhibo-10055601.file.myqcloud.com/coverImg.jpg";
static const ARGUMENT_TYPE_POS = "arg_type_pos"; static const ARGUMENT_TYPE_POS = "arg_type_pos";
...@@ -125,11 +126,17 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto ...@@ -125,11 +126,17 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto
} }
void _jumpToDownloadList() async { void _jumpToDownloadList() async {
bool needResume = false;
if (_controller.playerState == SuperPlayerState.PLAYING) {
_controller.pause();
needResume = true;
}
dynamic result = await Navigator.push(context, MaterialPageRoute(builder: (context) => DemoDownloadList())); dynamic result = await Navigator.push(context, MaterialPageRoute(builder: (context) => DemoDownloadList()));
if(result is SuperPlayerModel) { if (result is SuperPlayerModel) {
playVideo(result); playVideo(result);
} else { } else if (needResume) {
print("download list return result is not a videoModel, result is :$result"); _controller.resume();
LogUtils.v(TAG, "download list return result is not a videoModel, result is :$result");
} }
} }
...@@ -231,9 +238,10 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto ...@@ -231,9 +238,10 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto
"", "",
0, 0,
"", "",
(String url, int appId, String fileId, String pSign) { (String url, int appId, String fileId, String pSign, bool enableDownload) {
SuperPlayerModel model = new SuperPlayerModel(); SuperPlayerModel model = new SuperPlayerModel();
model.appId = appId; model.appId = appId;
model.isEnableDownload = enableDownload;
if (url.isNotEmpty) { if (url.isNotEmpty) {
model.videoURL = url; model.videoURL = url;
model.coverUrl = DEFAULT_PLACE_HOLDER; model.coverUrl = DEFAULT_PLACE_HOLDER;
...@@ -255,6 +263,7 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto ...@@ -255,6 +263,7 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto
}, },
needPisgn: !isLive, needPisgn: !isLive,
showFileEdited: !isLive, showFileEdited: !isLive,
needDownload: !isLive,
); );
}); });
} }
...@@ -388,13 +397,16 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto ...@@ -388,13 +397,16 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto
await Future.wait(requestList); await Future.wait(requestList);
videoModels.clear(); videoModels.clear();
videoModels.addAll(models); videoModels.addAll(models);
setState(() {
if (videoModels.isNotEmpty) { if(mounted) {
playVideo(videoModels[0]); setState(() {
} else { if (videoModels.isNotEmpty) {
EasyLoading.showError("video list request error"); playVideo(videoModels[0]);
} } else {
}); EasyLoading.showError("video list request error");
}
});
}
} }
@override @override
......
...@@ -307,7 +307,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO ...@@ -307,7 +307,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
showDialog( showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
return DemoInputDialog("", 0, "", (String url, int appId, String fileId, String pSign) { return DemoInputDialog("", 0, "", (String url, int appId, String fileId, String pSign, bool enableDownload) {
_url = url; _url = url;
_controller.stop(); _controller.stop();
if (url.isNotEmpty) { if (url.isNotEmpty) {
......
...@@ -389,7 +389,7 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer> ...@@ -389,7 +389,7 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer>
context: context, context: context,
builder: (context) { builder: (context) {
return DemoInputDialog("", 0, "", return DemoInputDialog("", 0, "",
(String url, int appId, String fileId,String pSign) { (String url, int appId, String fileId,String pSign, bool enableDownload) {
_url = url; _url = url;
_appId = appId; _appId = appId;
_fileId = fileId; _fileId = fileId;
......
...@@ -125,7 +125,27 @@ ...@@ -125,7 +125,27 @@
TXVodDownloadMediaInfo *mediaInfo = [self parseMediaInfoFromInfo:quality url:videoUrl appId:appIdNum fileId:fileId name:userName]; TXVodDownloadMediaInfo *mediaInfo = [self parseMediaInfoFromInfo:quality url:videoUrl appId:appIdNum fileId:fileId name:userName];
BOOL deleteResult = [[TXVodDownloadManager shareInstance] deleteDownloadMediaInfo:mediaInfo]; BOOL deleteResult = [[TXVodDownloadManager shareInstance] deleteDownloadMediaInfo:mediaInfo];
result(@(deleteResult)); result(@(deleteResult));
} else if([@"resumeDownload" isEqualToString:call.method]) {
NSNumber *quality = args[@"quality"];
NSString *videoUrl = args[@"url"];
NSNumber *appIdNum = args[@"appId"];
NSString *fileId = args[@"fileId"];
NSString *pSign = args[@"pSign"];
NSString *userName = args[@"userName"];
TXVodDownloadMediaInfo *mediaInfo = [self parseMediaInfoFromInfo:quality url:videoUrl appId:appIdNum fileId:fileId name:userName];
BOOL deleteResult = NO;
if (nil != mediaInfo) {
TXVodDownloadDataSource *dataSource = mediaInfo.dataSource;
if (nil != dataSource) {
[[TXVodDownloadManager shareInstance] startDownload:dataSource];
} else {
[[TXVodDownloadManager shareInstance] startDownload:mediaInfo.userName url:mediaInfo.url];
}
deleteResult = YES;
}
result(@(deleteResult));
} }
} }
......
...@@ -132,6 +132,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; ...@@ -132,6 +132,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
[_netStatusChannel setStreamHandler:nil]; [_netStatusChannel setStreamHandler:nil];
_netStatusChannel = nil; _netStatusChannel = nil;
[self releaseImageSprite];
} }
- (void)setupPlayerWithBool:(BOOL)onlyAudio - (void)setupPlayerWithBool:(BOOL)onlyAudio
...@@ -158,7 +159,6 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; ...@@ -158,7 +159,6 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
_txVodPlayer.vodDelegate = self; _txVodPlayer.vodDelegate = self;
[self setupPlayerWithBool:onlyAudio]; [self setupPlayerWithBool:onlyAudio];
} }
_txImageSprite = [[TXImageSprite alloc] init];
return [NSNumber numberWithLongLong:_textureId]; return [NSNumber numberWithLongLong:_textureId];
} }
...@@ -198,6 +198,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; ...@@ -198,6 +198,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
if (_txVodPlayer != nil) { if (_txVodPlayer != nil) {
return [_txVodPlayer stopPlay]; return [_txVodPlayer stopPlay];
} }
[self releaseImageSprite];
return NO; return NO;
} }
...@@ -299,6 +300,48 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; ...@@ -299,6 +300,48 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
} }
} }
- (void)releaseImageSprite
{
if(_txImageSprite) {
_txImageSprite = nil;
}
}
- (void)setImageSprite:(NSString*)urlStr withImgArray:(NSArray*)imgStrArray result:(FlutterResult)result {
[self releaseImageSprite];
_txImageSprite = [[TXImageSprite alloc] init];
NSMutableArray *imageUrls = @[].mutableCopy;
NSURL *vvtUrl = nil;
if(imgStrArray && [NSNull null] != (NSNull *)imgStrArray) {
for(NSString *url in imgStrArray) {
NSURL *nsurl = [NSURL URLWithString:url];
if (nsurl) {
[imageUrls addObject:nsurl];
}
}
}
if(urlStr && [NSNull null] != (NSNull *)urlStr) {
vvtUrl = [NSURL URLWithString:urlStr];
}
[_txImageSprite setVTTUrl:vvtUrl imageUrls:imageUrls];
result(nil);
}
- (void)getImageSprite:(NSNumber*)time result:(FlutterResult)result {
if(_txImageSprite && [NSNull null] != (NSNull*)time) {
UIImage *imageSprite = [_txImageSprite getThumbnail:time.floatValue];
if(nil != imageSprite) {
NSData *data = UIImagePNGRepresentation(imageSprite);
result(data);
} else {
result(nil);
}
} else {
NSLog(@"getImageSprite failed, time is null or initImageSprite not invoke");
result(nil);
}
}
#pragma mark - #pragma mark -
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result
...@@ -439,27 +482,12 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; ...@@ -439,27 +482,12 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
NSDictionary *args = call.arguments; NSDictionary *args = call.arguments;
NSString *vvtStr = args[@"vvtUrl"]; NSString *vvtStr = args[@"vvtUrl"];
NSArray *imageStrs = args[@"imageUrls"]; NSArray *imageStrs = args[@"imageUrls"];
[self setImageSprite:vvtStr withImgArray:imageStrs result:result];
NSMutableArray *imageUrls = @[].mutableCopy;
for(NSString *url in imageStrs) {
NSURL *nsurl = [NSURL URLWithString:url];
if (nsurl) {
[imageUrls addObject:nsurl];
}
}
[_txImageSprite setVTTUrl: [NSURL URLWithString:vvtStr] imageUrls:imageUrls];
result(nil);
} }
else if ([@"getImageSprite" isEqualToString:call.method]) { else if ([@"getImageSprite" isEqualToString:call.method]) {
NSDictionary *args = call.arguments; NSDictionary *args = call.arguments;
NSInteger time = [args[@"time"] intValue]; NSNumber *time = args[@"time"];
UIImage *imageSprite = [_txImageSprite getThumbnail:time]; [self getImageSprite:time result:result];
if(nil != imageSprite) {
NSData *data = UIImagePNGRepresentation(imageSprite);
result(data);
} else {
result(nil);
}
} }
else if ([@"exitPictureInPictureMode" isEqualToString:call.method]) { else if ([@"exitPictureInPictureMode" isEqualToString:call.method]) {
if(_txVodPlayer != nil) { if(_txVodPlayer != nil) {
...@@ -760,7 +788,8 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; ...@@ -760,7 +788,8 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
- (UIView *)txPipView { - (UIView *)txPipView {
if (!_txPipView) { if (!_txPipView) {
_txPipView = [[UIView alloc] initWithFrame:CGRectZero]; // 给定1像素的大小,使得画中画正常显示
_txPipView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
_txPipView.hidden = YES; _txPipView.hidden = YES;
} }
return _txPipView; return _txPipView;
......
...@@ -66,11 +66,17 @@ class TXVodDownloadController { ...@@ -66,11 +66,17 @@ class TXVodDownloadController {
/// 开始下载 /// 开始下载
/// videoDownloadModel: 下载构造体 [TXVodDownloadMediaInfo] /// videoDownloadModel: 下载构造体 [TXVodDownloadMediaInfo]
/// userName: 下载用户,用来区分不同用户的下载,可不传,不传则使用默认值
Future<void> startDownload(TXVodDownloadMediaInfo mediaInfo) async { Future<void> startDownload(TXVodDownloadMediaInfo mediaInfo) async {
await _methodChannel.invokeMethod("startDownload", mediaInfo.toJson()); await _methodChannel.invokeMethod("startDownload", mediaInfo.toJson());
} }
/// 继续下载,与开始下载接口有区别,该接口会寻找对应的缓存,复用之前的缓存来续点下载,
/// 而开始下载接口会启动一个全新的下载
/// videoDownloadModel: 下载构造体 [TXVodDownloadMediaInfo]
Future<void> resumeDownload(TXVodDownloadMediaInfo mediaInfo) async {
await _methodChannel.invokeMethod("resumeDownload", mediaInfo.toJson());
}
/// 停止下载 /// 停止下载
/// videoDownloadModel: 下载构造体 [TXVodDownloadMediaInfo] /// videoDownloadModel: 下载构造体 [TXVodDownloadMediaInfo]
Future<void> stopDownload(TXVodDownloadMediaInfo mediaInfo) async { Future<void> stopDownload(TXVodDownloadMediaInfo mediaInfo) async {
......
...@@ -412,7 +412,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX ...@@ -412,7 +412,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
} }
} }
Future<void> initImageSprite(String vvtUrl, List<String> imageUrls) async { Future<void> initImageSprite(String? vvtUrl, List<String>? imageUrls) async {
if (_isNeedDisposed) return; if (_isNeedDisposed) return;
await _initPlayer.future; await _initPlayer.future;
await _channel.invokeMethod("initImageSprite", {"vvtUrl":vvtUrl, "imageUrls":imageUrls}); await _channel.invokeMethod("initImageSprite", {"vvtUrl":vvtUrl, "imageUrls":imageUrls});
......
...@@ -82,6 +82,10 @@ class DownloadHelper { ...@@ -82,6 +82,10 @@ class DownloadHelper {
return TXVodDownloadController.instance.startDownload(mediaInfo); return TXVodDownloadController.instance.startDownload(mediaInfo);
} }
Future<void> resumeDownloadOrg(TXVodDownloadMediaInfo mediaInfo) async {
return TXVodDownloadController.instance.resumeDownload(mediaInfo);
}
Future<bool> deleteDownload(TXVodDownloadMediaInfo mediaInfo) async { Future<bool> deleteDownload(TXVodDownloadMediaInfo mediaInfo) async {
return TXVodDownloadController.instance.deleteDownloadMediaInfo(mediaInfo); return TXVodDownloadController.instance.deleteDownloadMediaInfo(mediaInfo);
} }
......
...@@ -329,6 +329,8 @@ class SuperPlayerController { ...@@ -329,6 +329,8 @@ class SuperPlayerController {
_observer?.onVideoImageSpriteAndKeyFrameChanged(spriteInfo, keyFrameInfo); _observer?.onVideoImageSpriteAndKeyFrameChanged(spriteInfo, keyFrameInfo);
if (null != spriteInfo) { if (null != spriteInfo) {
_vodPlayerController.initImageSprite(spriteInfo.webVttUrl, spriteInfo.imageUrls); _vodPlayerController.initImageSprite(spriteInfo.webVttUrl, spriteInfo.imageUrls);
} else {
_vodPlayerController.initImageSprite(null, null);
} }
this.spriteInfo = spriteInfo; this.spriteInfo = spriteInfo;
this.keyFrameInfo = keyFrameInfo; this.keyFrameInfo = keyFrameInfo;
......
...@@ -79,9 +79,7 @@ class TXPipController { ...@@ -79,9 +79,7 @@ class TXPipController {
Future<void> exitAndReleaseCurrentPip() async { Future<void> exitAndReleaseCurrentPip() async {
if (null != _playerData && _playerData?._playerController != null) { if (null != _playerData && _playerData?._playerController != null) {
if (Platform.isAndroid) { await _playerData?._playerController.exitPictureInPictureMode();
await _playerData?._playerController.exitPictureInPictureMode();
}
await _playerData?._playerController.stop(); await _playerData?._playerController.stop();
_playerData?._playerController.dispose(); _playerData?._playerController.dispose();
} }
......
...@@ -149,6 +149,8 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs ...@@ -149,6 +149,8 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs
_playController._observer = _SuperPlayerObserver(() { _playController._observer = _SuperPlayerObserver(() {
// preparePlayVideo // preparePlayVideo
setState(() { setState(() {
_currentSprite = null;
_isShowSprite = false;
_isShowControlView = false; _isShowControlView = false;
_isLoading = _playController.videoModel!.playAction == SuperPlayerModel.PLAY_ACTION_AUTO_PLAY; _isLoading = _playController.videoModel!.playAction == SuperPlayerModel.PLAY_ACTION_AUTO_PLAY;
}); });
...@@ -334,7 +336,8 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs ...@@ -334,7 +336,8 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs
} }
void _calculateSize(double videoWidth, double videoHeight) { void _calculateSize(double videoWidth, double videoHeight) {
if ((0 != videoWidth && 0 != videoHeight) && (_videoWidth != videoWidth && _videoHeight != videoHeight)) { if (mounted && (0 != videoWidth && 0 != videoHeight) &&
(_videoWidth != videoWidth && _videoHeight != videoHeight)) {
_videoWidth = videoWidth; _videoWidth = videoWidth;
_videoHeight = videoHeight; _videoHeight = videoHeight;
_resizeVideo(); _resizeVideo();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论