Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
T
tx_player_fork
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蒋俊
tx_player_fork
Commits
83a8f6a8
提交
83a8f6a8
authored
6月 20, 2022
作者:
dokieyang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
1、fix bug: play with fileId & psign
2、add more features to SuperPlayer panel
上级
4ac57839
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
76 个修改的文件
包含
880 行增加
和
479 行删除
+880
-479
README.md
Flutter/README.md
+19
-5
build.gradle
Flutter/android/build.gradle
+1
-1
FTXBasePlayer.java
.../src/main/java/com/tencent/vod/flutter/FTXBasePlayer.java
+2
-1
FTXEvent.java
...droid/src/main/java/com/tencent/vod/flutter/FTXEvent.java
+20
-0
FTXLivePlayer.java
.../src/main/java/com/tencent/vod/flutter/FTXLivePlayer.java
+2
-2
FTXPlayerEventSink.java
...main/java/com/tencent/vod/flutter/FTXPlayerEventSink.java
+1
-0
FTXTransformation.java
.../main/java/com/tencent/vod/flutter/FTXTransformation.java
+1
-0
FTXVodPlayer.java
...d/src/main/java/com/tencent/vod/flutter/FTXVodPlayer.java
+32
-7
SuperPlayerPlugin.java
.../main/java/com/tencent/vod/flutter/SuperPlayerPlugin.java
+0
-0
点播播放器.md
Flutter/docs/点播播放器.md
+1
-1
.gitignore
Flutter/example/.gitignore
+2
-0
build.gradle
Flutter/example/android/app/build.gradle
+2
-2
superplayer_ic_light_max.png
Flutter/example/images/superplayer_ic_light_max.png
+0
-0
superplayer_ic_light_min.png
Flutter/example/images/superplayer_ic_light_min.png
+0
-0
superplayer_ic_vod_more_normal.png
Flutter/example/images/superplayer_ic_vod_more_normal.png
+0
-0
superplayer_ic_volume_max.png
Flutter/example/images/superplayer_ic_volume_max.png
+0
-0
superplayer_ic_volume_min.png
Flutter/example/images/superplayer_ic_volume_min.png
+0
-0
.gitignore
Flutter/example/ios/.gitignore
+1
-1
Podfile.lock
Flutter/example/ios/Podfile.lock
+0
-35
demo_superplayer.dart
Flutter/example/lib/demo_superplayer.dart
+14
-11
demo_txLiveplayer.dart
Flutter/example/lib/demo_txLiveplayer.dart
+43
-37
demo_txvodplayer.dart
Flutter/example/lib/demo_txvodplayer.dart
+0
-0
main.dart
Flutter/example/lib/main.dart
+2
-0
play_info_parser_v2.dart
Flutter/example/lib/superplayer/cgi/play_info_parser_v2.dart
+1
-1
play_info_parser_v4.dart
Flutter/example/lib/superplayer/cgi/play_info_parser_v4.dart
+8
-3
playinfo_parser.dart
Flutter/example/lib/superplayer/cgi/playinfo_parser.dart
+1
-0
playinfo_protocol.dart
Flutter/example/lib/superplayer/cgi/playinfo_protocol.dart
+23
-2
super_vod_data_loader.dart
...er/example/lib/superplayer/cgi/super_vod_data_loader.dart
+6
-24
color_resource.dart
Flutter/example/lib/superplayer/common/color_resource.dart
+3
-0
string_resource.dart
Flutter/example/lib/superplayer/common/string_resource.dart
+6
-0
theme_resource.dart
Flutter/example/lib/superplayer/common/theme_resource.dart
+35
-0
demo_superplayer_lib.dart
Flutter/example/lib/superplayer/demo_superplayer_lib.dart
+7
-2
superplayer_define.dart
...ter/example/lib/superplayer/model/superplayer_define.dart
+1
-0
superplayer_model.dart
Flutter/example/lib/superplayer/model/superplayer_model.dart
+1
-0
superplayer_controller.dart
Flutter/example/lib/superplayer/superplayer_controller.dart
+39
-25
superplayer_observer.dart
Flutter/example/lib/superplayer/superplayer_observer.dart
+1
-0
video_quality_utils.dart
...er/example/lib/superplayer/tools/video_quality_utils.dart
+1
-0
superplayer_bottom_view.dart
...r/example/lib/superplayer/ui/superplayer_bottom_view.dart
+2
-10
superplayer_cover_view.dart
...er/example/lib/superplayer/ui/superplayer_cover_view.dart
+89
-0
superplayer_more_view.dart
...ter/example/lib/superplayer/ui/superplayer_more_view.dart
+251
-0
superplayer_quality_view.dart
.../example/lib/superplayer/ui/superplayer_quality_view.dart
+3
-2
superplayer_title_view.dart
...er/example/lib/superplayer/ui/superplayer_title_view.dart
+34
-8
superplayer_widget.dart
Flutter/example/lib/superplayer/ui/superplayer_widget.dart
+0
-0
demo_bitrate_checkbox.dart
Flutter/example/lib/ui/demo_bitrate_checkbox.dart
+1
-2
demo_define.dart
Flutter/example/lib/ui/demo_define.dart
+1
-0
demo_expansion_list_item.dart
Flutter/example/lib/ui/demo_expansion_list_item.dart
+1
-1
demo_expansion_panel_list.dart
Flutter/example/lib/ui/demo_expansion_panel_list.dart
+1
-1
demo_inputdialog.dart
Flutter/example/lib/ui/demo_inputdialog.dart
+33
-4
demo_speed_slider.dart
Flutter/example/lib/ui/demo_speed_slider.dart
+1
-1
demo_video_slider_view.dart
Flutter/example/lib/ui/demo_video_slider_view.dart
+1
-0
demo_volume_slider.dart
Flutter/example/lib/ui/demo_volume_slider.dart
+1
-1
treePage.dart
Flutter/example/lib/ui/treePage.dart
+1
-0
pubspec.lock
Flutter/example/pubspec.lock
+0
-182
pubspec.yaml
Flutter/example/pubspec.yaml
+5
-0
FTXBasePlayer.h
Flutter/ios/Classes/FTXBasePlayer.h
+1
-6
FTXBasePlayer.m
Flutter/ios/Classes/FTXBasePlayer.m
+1
-6
FTXEvent.h
Flutter/ios/Classes/FTXEvent.h
+10
-0
FTXLivePlayer.h
Flutter/ios/Classes/FTXLivePlayer.h
+1
-6
FTXLivePlayer.m
Flutter/ios/Classes/FTXLivePlayer.m
+1
-7
FTXPlayerEventSinkQueue.h
Flutter/ios/Classes/FTXPlayerEventSinkQueue.h
+1
-6
FTXPlayerEventSinkQueue.m
Flutter/ios/Classes/FTXPlayerEventSinkQueue.m
+1
-6
FTXTransformation.h
Flutter/ios/Classes/FTXTransformation.h
+1
-0
FTXTransformation.m
Flutter/ios/Classes/FTXTransformation.m
+1
-0
FTXVodPlayer.h
Flutter/ios/Classes/FTXVodPlayer.h
+1
-6
FTXVodPlayer.m
Flutter/ios/Classes/FTXVodPlayer.m
+20
-14
SuperPlayerPlugin.h
Flutter/ios/Classes/SuperPlayerPlugin.h
+1
-0
SuperPlayerPlugin.m
Flutter/ios/Classes/SuperPlayerPlugin.m
+0
-0
superplayer_plugin.dart
Flutter/lib/Core/superplayer_plugin.dart
+76
-0
log_utils.dart
Flutter/lib/Core/tools/log_utils.dart
+1
-0
txliveplayer_controller.dart
Flutter/lib/Core/txliveplayer_controller.dart
+1
-1
txplayer_controller.dart
Flutter/lib/Core/txplayer_controller.dart
+1
-1
txplayer_define.dart
Flutter/lib/Core/txplayer_define.dart
+17
-0
txplayer_widget.dart
Flutter/lib/Core/txplayer_widget.dart
+37
-36
txvodplayer_config.dart
Flutter/lib/Core/txvodplayer_config.dart
+1
-0
txvodplayer_controller.dart
Flutter/lib/Core/txvodplayer_controller.dart
+4
-11
super_player.dart
Flutter/lib/super_player.dart
+1
-1
没有找到文件。
Flutter/README.md
浏览文件 @
83a8f6a8
...
...
@@ -116,7 +116,7 @@ pod 'TXLiteAVSDK_Professional' //Professional版
### 集成过程中常见问题
执行
`flutter doctor`
命令检查运行环境,
知道
出现”No issues found!“。
执行
`flutter doctor`
命令检查运行环境,
直到
出现”No issues found!“。
执行
`flutter pub get`
确保所有依赖的组件都已更新成功。
...
...
@@ -175,10 +175,17 @@ class _TestState extends State<Test> {
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
height:
220
,
color:
Colors
.
black
,
child:
AspectRatio
(
aspectRatio:
_aspectRatio
,
child:
TXPlayerVideo
(
controller:
_controller
)));
return
Scaffold
(
body:
Container
(
height:
220
,
color:
Colors
.
black
,
child:
AspectRatio
(
aspectRatio:
_aspectRatio
,
child:
TXPlayerVideo
(
controller:
_controller
))));
}
@override
void
dispose
()
{
_controller
.
dispose
();
super
.
dispose
();
}
}
```
...
...
@@ -301,6 +308,13 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
model
.
title
=
"腾讯云音视频"
;
_controller
.
playWithModel
(
model
);
}
@override
void
dispose
()
{
// must invoke when page exit.
_controller
.
releasePlayer
();
super
.
dispose
();
}
}
```
...
...
Flutter/android/build.gradle
浏览文件 @
83a8f6a8
...
...
@@ -48,7 +48,7 @@ android {
dependencies
{
compileOnly
'androidx.annotation:annotation:1.2.0'
//此处仅处理因插件项目内报红显示的处理方式
//
compileOnly files("$flutterRoot/bin/cache/artifacts/engine/android-arm/flutter.jar")
//
compileOnly files("$flutterRoot/bin/cache/artifacts/engine/android-arm/flutter.jar")
}
}
...
...
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXBasePlayer.java
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
package
com
.
tencent
.
vod
.
flutter
;
import
java.util.concurrent.atomic.AtomicInteger
;
...
...
@@ -16,7 +17,7 @@ public class FTXBasePlayer {
mPlayerId
=
mAtomicId
.
incrementAndGet
();
}
public
void
dest
or
y
()
{
public
void
dest
ro
y
()
{
}
...
...
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXEvent.java
0 → 100644
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
package
com
.
tencent
.
vod
.
flutter
;
/**
* 通用事件码
*/
public
class
FTXEvent
{
/*
音量变化
*/
public
static
final
int
EVENT_VOLUME_CHANGED
=
0x01
;
/*
失去音量输出播放焦点
*/
public
static
final
int
EVENT_AUDIO_FOCUS_PAUSE
=
0x02
;
/*
获得音量输出焦点
*/
public
static
final
int
EVENT_AUDIO_FOCUS_PLAY
=
0x03
;
}
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXLivePlayer.java
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
package
com
.
tencent
.
vod
.
flutter
;
import
android.app.Activity
;
...
...
@@ -87,7 +88,7 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
}
@Override
public
void
dest
or
y
()
{
public
void
dest
ro
y
()
{
if
(
mLivePlayer
!=
null
)
{
mLivePlayer
.
stopPlay
(
true
);
mLivePlayer
=
null
;
...
...
@@ -203,7 +204,6 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
Log
.
d
(
TAG
,
"startPlay:"
);
if
(
mLivePlayer
!=
null
)
{
mLivePlayer
.
setSurface
(
mSurface
);
mLivePlayer
.
enableHardwareDecode
(
true
);
mLivePlayer
.
setPlayListener
(
this
);
TXLivePlayConfig
config
=
new
TXLivePlayConfig
();
config
.
setEnableMessage
(
true
);
...
...
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXPlayerEventSink.java
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
package
com
.
tencent
.
vod
.
flutter
;
import
java.util.LinkedList
;
...
...
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXTransformation.java
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
package
com
.
tencent
.
vod
.
flutter
;
import
android.text.TextUtils
;
...
...
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXVodPlayer.java
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
package
com
.
tencent
.
vod
.
flutter
;
import
android.graphics.Bitmap
;
...
...
@@ -50,6 +51,9 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
private
static
final
int
Uninitialized
=
-
101
;
private
TextureRegistry
.
SurfaceTextureEntry
mSurfaceTextureEntry
;
private
boolean
mEnableHardwareDecode
=
true
;
private
boolean
mHardwareDecodeFail
=
false
;
public
FTXVodPlayer
(
FlutterPlugin
.
FlutterPluginBinding
flutterPluginBinding
)
{
super
();
...
...
@@ -87,7 +91,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
@Override
public
void
dest
or
y
()
{
public
void
dest
ro
y
()
{
if
(
mVodPlayer
!=
null
)
{
mVodPlayer
.
stopPlay
(
true
);
mVodPlayer
=
null
;
...
...
@@ -114,8 +118,8 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
}
@Override
public
void
onPlayEvent
(
TXVodPlayer
txVodPlayer
,
int
i
,
Bundle
bundle
)
{
if
(
i
==
TXLiveConstants
.
PLAY_EVT_CHANGE_RESOLUTION
)
{
public
void
onPlayEvent
(
TXVodPlayer
txVodPlayer
,
int
event
,
Bundle
bundle
)
{
if
(
event
==
TXLiveConstants
.
PLAY_EVT_CHANGE_RESOLUTION
)
{
String
EVT_PARAM3
=
bundle
.
getString
(
"EVT_PARAM3"
);
if
(!
TextUtils
.
isEmpty
(
EVT_PARAM3
))
{
String
[]
array
=
EVT_PARAM3
.
split
(
","
);
...
...
@@ -132,14 +136,33 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
bundle
.
putInt
(
"videoTop"
,
videoTop
);
bundle
.
putInt
(
"videoRight"
,
videoRight
);
bundle
.
putInt
(
"videoBottom"
,
videoBottom
);
mEventSink
.
success
(
getParams
(
i
,
bundle
));
mEventSink
.
success
(
getParams
(
event
,
bundle
));
return
;
}
}
int
width
=
bundle
.
getInt
(
TXLiveConstants
.
EVT_PARAM1
,
0
);
int
height
=
bundle
.
getInt
(
TXLiveConstants
.
EVT_PARAM2
,
0
);
if
(!
mEnableHardwareDecode
||
mHardwareDecodeFail
)
{
setDefaultBufferSizeForSoftDecode
(
width
,
height
);
}
}
else
if
(
event
==
TXLiveConstants
.
PLAY_WARNING_HW_ACCELERATION_FAIL
)
{
mHardwareDecodeFail
=
true
;
}
mEventSink
.
success
(
getParams
(
event
,
bundle
));
}
// surface 的大小默认是宽高为1,当硬解失败时或使用软解时,软解会依赖surface的窗口渲染,不更新会导致只有1px的内容
private
void
setDefaultBufferSizeForSoftDecode
(
int
width
,
int
height
)
{
mSurfaceTextureEntry
.
surfaceTexture
().
setDefaultBufferSize
(
width
,
height
);
if
(
mSurface
!=
null
)
{
mSurface
.
release
();
}
mEventSink
.
success
(
getParams
(
i
,
bundle
));
mSurface
=
new
Surface
(
mSurfaceTextureEntry
.
surfaceTexture
());
mVodPlayer
.
setSurface
(
mSurface
);
}
@Override
public
void
onNetStatus
(
TXVodPlayer
txVodPlayer
,
Bundle
bundle
)
{
mNetStatusSink
.
success
(
getParams
(
0
,
bundle
));
...
...
@@ -151,7 +174,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
boolean
onlyAudio
=
call
.
argument
(
"onlyAudio"
);
long
id
=
init
(
onlyAudio
);
result
.
success
(
id
);
}
else
if
(
call
.
method
.
equals
(
"set
Is
AutoPlay"
))
{
}
else
if
(
call
.
method
.
equals
(
"setAutoPlay"
))
{
boolean
loop
=
call
.
argument
(
"isAutoPlay"
);
setIsAutoPlay
(
loop
);
result
.
success
(
null
);
...
...
@@ -285,6 +308,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
return
mSurfaceTextureEntry
==
null
?
-
1
:
mSurfaceTextureEntry
.
id
();
}
void
setPlayer
(
boolean
onlyAudio
)
{
if
(!
onlyAudio
)
{
mSurfaceTextureEntry
=
mFlutterPluginBinding
.
getTextureRegistry
().
createSurfaceTexture
();
...
...
@@ -293,7 +317,6 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
if
(
mVodPlayer
!=
null
)
{
mVodPlayer
.
setSurface
(
mSurface
);
mVodPlayer
.
enableHardwareDecode
(
true
);
}
}
}
...
...
@@ -342,6 +365,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
if
(
mVodPlayer
!=
null
)
{
return
mVodPlayer
.
stopPlay
(
isNeedClearLastImg
);
}
mHardwareDecodeFail
=
false
;
return
Uninitialized
;
}
...
...
@@ -520,6 +544,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
boolean
enableHardwareDecode
(
boolean
enable
)
{
if
(
mVodPlayer
!=
null
)
{
mEnableHardwareDecode
=
enable
;
return
mVodPlayer
.
enableHardwareDecode
(
enable
);
}
return
false
;
...
...
Flutter/android/src/main/java/com/tencent/vod/flutter/SuperPlayerPlugin.java
浏览文件 @
83a8f6a8
差异被折叠。
点击展开。
Flutter/docs/点播播放器.md
浏览文件 @
83a8f6a8
...
...
@@ -737,7 +737,7 @@ _controller.onPlayerState.listen((val) { });
!
[
](https://mc.qcloudimg.com/static/img/7331417ebbdfe6306fe96f4b76c8d0ad/image.jpg)
```
dart
// 播放视频 A: 如果将 isAutoPlay 设置为
YES
, 那么 startPlay 调用会立刻开始视频的加载和播放
// 播放视频 A: 如果将 isAutoPlay 设置为
true
, 那么 startPlay 调用会立刻开始视频的加载和播放
String
url_A
=
"http://1252463788.vod2.myqcloud.com/xxxxx/v.f10.mp4"
;
await
_controller_A
.
setIsAutoPlay
(
isAutoPlay:
true
);
await
_controller_A
.
play
(
url_A
);
...
...
Flutter/example/.gitignore
浏览文件 @
83a8f6a8
...
...
@@ -44,3 +44,4 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
pubspec.lock
\ No newline at end of file
Flutter/example/android/app/build.gradle
浏览文件 @
83a8f6a8
...
...
@@ -25,13 +25,13 @@ apply plugin: 'com.android.application'
apply
from:
"$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android
{
compileSdkVersion
28
compileSdkVersion
31
defaultConfig
{
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId
"com.example.super_player_example"
minSdkVersion
19
targetSdkVersion
28
targetSdkVersion
31
versionCode
flutterVersionCode
.
toInteger
()
versionName
flutterVersionName
}
...
...
Flutter/example/images/superplayer_ic_light_max.png
0 → 100644
浏览文件 @
83a8f6a8
2.2 KB
Flutter/example/images/superplayer_ic_light_min.png
0 → 100644
浏览文件 @
83a8f6a8
1.2 KB
Flutter/example/images/superplayer_ic_vod_more_normal.png
0 → 100644
浏览文件 @
83a8f6a8
2.4 KB
Flutter/example/images/superplayer_ic_volume_max.png
0 → 100644
浏览文件 @
83a8f6a8
1.9 KB
Flutter/example/images/superplayer_ic_volume_min.png
0 → 100644
浏览文件 @
83a8f6a8
1.1 KB
Flutter/example/ios/.gitignore
浏览文件 @
83a8f6a8
...
...
@@ -24,7 +24,7 @@ Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
/Podfile.lock
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
...
...
Flutter/example/ios/Podfile.lock
deleted
100644 → 0
浏览文件 @
4ac57839
PODS:
- auto_orientation (0.0.1):
- Flutter
- Flutter (1.0.0)
- super_player (1.0.1):
- Flutter
- TXLiteAVSDK_Player
- TXLiteAVSDK_Player (9.5.29016)
DEPENDENCIES:
- auto_orientation (from `.symlinks/plugins/auto_orientation/ios`)
- Flutter (from `Flutter`)
- super_player (from `.symlinks/plugins/super_player/ios`)
SPEC REPOS:
trunk:
- TXLiteAVSDK_Player
EXTERNAL SOURCES:
auto_orientation:
:path: ".symlinks/plugins/auto_orientation/ios"
Flutter:
:path: Flutter
super_player:
:path: ".symlinks/plugins/super_player/ios"
SPEC CHECKSUMS:
auto_orientation: 2941c44ebe5c3d41016001597ab03e81a92a26ce
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
super_player: 7704aa01779b7093d5667994f382729b5e0b3ed6
TXLiteAVSDK_Player: 5a9cea3ba4e77fc8993b19523afbecdfc1a803ce
PODFILE CHECKSUM: 503cb461ebd1e4de100eb5092af3ca3f013abcd5
COCOAPODS: 1.11.3
Flutter/example/lib/demo_superplayer.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'package:flutter/material.dart'
;
import
'package:flutter_easyloading/flutter_easyloading.dart'
;
import
'package:super_player/super_player.dart'
;
...
...
@@ -26,13 +27,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
_controller
.
onSimplePlayerEventBroadcast
.
listen
((
event
)
{
String
evtName
=
event
[
"event"
];
if
(
evtName
==
SuperPlayerViewEvent
.
onStartFullScreenPlay
)
{
setState
(()
{
_isFullScreen
=
true
;
});
}
else
if
(
evtName
==
SuperPlayerViewEvent
.
onStopFullScreenPlay
)
{
setState
(()
{
_isFullScreen
=
false
;
});
}
else
{
print
(
evtName
);
}
...
...
@@ -122,7 +117,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
showDialog
(
context:
context
,
builder:
(
context
)
{
return
DemoInputDialog
(
""
,
0
,
""
,
(
String
url
,
int
appId
,
String
fileId
)
{
return
DemoInputDialog
(
""
,
0
,
""
,
(
String
url
,
int
appId
,
String
fileId
,
String
pSign
)
{
SuperPlayerModel
model
=
new
SuperPlayerModel
();
model
.
appId
=
appId
;
if
(
url
.
isNotEmpty
)
{
...
...
@@ -130,13 +125,16 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
}
else
if
(
appId
!=
0
&&
fileId
.
isNotEmpty
)
{
model
.
videoId
=
new
SuperPlayerVideoId
();
model
.
videoId
!.
fileId
=
fileId
;
if
(
pSign
.
isNotEmpty
)
{
model
.
videoId
!.
psign
=
pSign
;
}
}
else
{
EasyLoading
.
showError
(
"请输入播放地址!"
);
return
;
}
playCurrentModel
(
model
);
});
}
,
needPisgn:
true
);
});
}
...
...
@@ -153,14 +151,17 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
model
.
appId
=
1500005830
;
model
.
videoId
=
new
SuperPlayerVideoId
();
model
.
videoId
!.
fileId
=
"8602268011437356984"
;
model
.
title
=
"云点播"
;
model
.
title
=
"云点播
(fileId播放)
"
;
model
.
playAction
=
playAction
;
models
.
add
(
model
);
model
=
SuperPlayerModel
();
model
.
appId
=
1252463788
;
model
.
appId
=
1254432039
;
model
.
title
=
"为什么贫穷(fileId+psign播放)"
;
model
.
videoId
=
new
SuperPlayerVideoId
();
model
.
videoId
!.
fileId
=
"5285890781763144364"
;
model
.
videoId
!.
fileId
=
'5285890816303742312'
;
model
.
videoId
!.
psign
=
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBJZCI6MTI1NDQzMjAzOSwiZmlsZUlkIjoiNTI4NTg5MDgxNjMwMzc0MjMxMiIsImN1cnJlbnRUaW1lU3RhbXAiOjE2MTcyNTc0ODMsInBjZmciOiJiYXNpY0RybVByZXNldCIsInVybEFjY2Vzc0luZm8iOnt9LCJkcm1MaWNlbnNlSW5mbyI6e319.2H1t9dKPpdA41a8t1WwI631OWC18HGl60ccBDLylCKE'
;
model
.
playAction
=
playAction
;
models
.
add
(
model
);
...
...
@@ -215,6 +216,8 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
void
dispose
()
{
// must invoke when page exit.
_controller
.
releasePlayer
();
// restore page brightness
SuperPlayerPlugin
.
restorePageBrightness
();
super
.
dispose
();
}
}
Flutter/example/lib/demo_txLiveplayer.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'dart:async'
;
import
'package:flutter/material.dart'
;
...
...
@@ -13,10 +14,9 @@ class DemoTXLivePlayer extends StatefulWidget {
_DemoTXLivelayerState
createState
()
=>
_DemoTXLivelayerState
();
}
class
_DemoTXLivelayerState
extends
State
<
DemoTXLivePlayer
>
with
WidgetsBindingObserver
{
class
_DemoTXLivelayerState
extends
State
<
DemoTXLivePlayer
>
with
WidgetsBindingObserver
{
late
TXLivePlayerController
_controller
;
double
_aspectRatio
=
0
;
double
_aspectRatio
=
16.0
/
9.
0
;
double
_progress
=
0.0
;
int
_volume
=
100
;
bool
_isMute
=
false
;
...
...
@@ -32,22 +32,31 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
_controller
=
TXLivePlayerController
();
_controller
.
onPlayerEventBroadcast
.
listen
((
event
)
{
//订阅事件分发
if
(
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_EVT_PLAY_PROGRESS
)
{
_controller
.
onPlayerEventBroadcast
.
listen
((
event
)
{
//订阅事件分发
if
(
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_EVT_PLAY_PROGRESS
)
{
_progress
=
event
[
"EVT_PLAY_PROGRESS"
].
toDouble
();
_maxLiveProgressTime
=
_progress
>=
_maxLiveProgressTime
?
_progress
:
_maxLiveProgressTime
;
progressSliderKey
.
currentState
?.
updatePorgess
(
1
,
_maxLiveProgressTime
);
}
else
if
(
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_EVT_PLAY_BEGIN
||
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_EVT_RCV_FIRST_I_FRAME
)
{
//首帧出现
}
else
if
(
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_EVT_PLAY_BEGIN
||
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_EVT_RCV_FIRST_I_FRAME
)
{
//首帧出现
_isStop
=
false
;
EasyLoading
.
dismiss
();
}
else
if
(
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_EVT_STREAM_SWITCH_SUCC
)
{
//切换流成功
}
else
if
(
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_EVT_STREAM_SWITCH_SUCC
)
{
//切换流成功
EasyLoading
.
dismiss
();
if
(
_url
==
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo1080p.flv"
)
{
EasyLoading
.
showSuccess
(
'切换到1080p!'
);
}
else
{
}
else
{
EasyLoading
.
showSuccess
(
'切换到480p!'
);
}
}
else
if
(
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_ERR_STREAM_SWITCH_FAIL
)
{
EasyLoading
.
dismiss
();
EasyLoading
.
showError
(
"切流失败"
);
switchUrl
();
}
else
if
(
event
[
"event"
]
==
TXVodPlayEvent
.
PLAY_EVT_CHANGE_RESOLUTION
)
{
LogUtils
.
w
(
"PLAY_EVT_CHANGE_RESOLUTION"
,
event
);
}
});
...
...
@@ -55,14 +64,15 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
double
w
=
(
event
[
TXVodNetEvent
.
NET_STATUS_VIDEO_WIDTH
]).
toDouble
();
double
h
=
(
event
[
TXVodNetEvent
.
NET_STATUS_VIDEO_HEIGHT
]).
toDouble
();
if
(
w
>
0
&&
h
>
0
)
{
if
(
w
>
0
&&
h
>
0
)
{
setState
(()
{
_aspectRatio
=
1.0
*
w
/
h
;
});
}
});
_controller
.
onPlayerState
.
listen
((
event
)
{
//订阅状态变化
_controller
.
onPlayerState
.
listen
((
event
)
{
//订阅状态变化
debugPrint
(
"播放状态
${event!.name}
"
);
});
...
...
@@ -98,6 +108,14 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
}
}
void
switchUrl
()
{
if
(
_url
==
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo480p.flv"
)
{
_url
=
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo1080p.flv"
;
}
else
{
_url
=
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo480p.flv"
;
}
}
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
...
...
@@ -116,7 +134,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
child:
Column
(
children:
[
Container
(
height:
2
5
0
,
height:
2
2
0
,
color:
Colors
.
black
,
child:
Center
(
child:
_aspectRatio
>
0
...
...
@@ -203,17 +221,8 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
EasyLoading
.
showError
(
'已经停止播放,请重新播放'
);
return
;
}
if
(
_url
==
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo480p.flv"
)
{
_url
=
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo1080p.flv"
;
_controller
.
switchStream
(
_url
);
}
else
{
_url
=
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo480p.flv"
;
_controller
.
switchStream
(
_url
);
}
switchUrl
();
_controller
.
switchStream
(
_url
);
EasyLoading
.
show
(
status:
'loading...'
);
},
...
...
@@ -241,17 +250,17 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
),
),
new
GestureDetector
(
onTap:
()
{
onClickVolume
();
},
child:
Container
(
alignment:
Alignment
.
center
,
child:
Text
(
"调整音量"
,
style:
TextStyle
(
fontSize:
18
,
color:
Colors
.
blue
),
),
onTap:
()
{
onClickVolume
();
},
child:
Container
(
alignment:
Alignment
.
center
,
child:
Text
(
"调整音量"
,
style:
TextStyle
(
fontSize:
18
,
color:
Colors
.
blue
),
),
),
),
],
)),
Expanded
(
...
...
@@ -260,9 +269,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
children:
[
Container
(
height:
100
,
child:
IconButton
(
icon:
new
Image
.
asset
(
'images/addp.png'
),
onPressed:
()
=>
{
onPressed
()}),
child:
IconButton
(
icon:
new
Image
.
asset
(
'images/addp.png'
),
onPressed:
()
=>
{
onPressed
()}),
)
],
)),
...
...
@@ -285,8 +292,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
showDialog
(
context:
context
,
builder:
(
context
)
{
return
DemoInputDialog
(
""
,
0
,
""
,
(
String
url
,
int
appId
,
String
fileId
)
{
return
DemoInputDialog
(
""
,
0
,
""
,
(
String
url
,
int
appId
,
String
fileId
,
String
pSign
)
{
_url
=
url
;
_controller
.
stop
();
if
(
url
.
isNotEmpty
)
{
...
...
Flutter/example/lib/demo_txvodplayer.dart
浏览文件 @
83a8f6a8
差异被折叠。
点击展开。
Flutter/example/lib/main.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'dart:async'
;
import
'package:flutter/material.dart'
;
...
...
@@ -25,6 +26,7 @@ class _MyAppState extends State<MyApp> {
super
.
initState
();
initPlatformState
();
initPlayerLicense
();
SystemChrome
.
setPreferredOrientations
([
DeviceOrientation
.
portraitUp
]);
LogUtils
.
logOpen
=
true
;
}
...
...
Flutter/example/lib/superplayer/cgi/play_info_parser_v2.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// v2 request data parser
...
...
@@ -58,7 +59,6 @@ class PlayInfoParserV2 implements PlayInfoParser {
int
code
=
root
[
'code'
];
String
message
=
root
[
'message'
];
String
warning
=
root
[
'warning'
];
LogUtils
.
d
(
TAG
,
"_getVodListData,code=
$code
,message=
$message
,warning=
$warning
"
);
if
(
code
!=
0
)
{
return
;
}
...
...
Flutter/example/lib/superplayer/cgi/play_info_parser_v4.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// v4 request data parser
...
...
@@ -95,9 +96,13 @@ class PlayInfoParserV4 implements PlayInfoParser {
if
(
null
!=
media
[
'imageSpriteInfo'
])
{
Map
<
String
,
dynamic
>
imageSpriteInfoJson
=
media
[
'imageSpriteInfo'
];
imageSpriteInfo
=
PlayImageSpriteInfo
();
imageSpriteInfo
?.
webVttUrl
=
imageSpriteInfoJson
[
'webVttUrl'
]
??
""
;
List
<
String
>
imageUrls
=
imageSpriteInfoJson
[
'imageUrls'
];
imageSpriteInfo
?.
imageUrls
=
imageUrls
;
if
(
imageSpriteInfoJson
!=
null
)
{
imageSpriteInfo
?.
webVttUrl
=
imageSpriteInfoJson
[
'webVttUrl'
]
??
""
;
List
<
String
>
imageUrls
=
imageSpriteInfoJson
[
'imageUrls'
]
==
null
?
List
.
empty
()
:
imageSpriteInfoJson
[
'imageUrls'
].
cast
<
String
>();
imageSpriteInfo
?.
imageUrls
=
imageUrls
;
}
}
_parseKeyFrameDescList
(
media
);
...
...
Flutter/example/lib/superplayer/cgi/playinfo_parser.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// play info parser interface
...
...
Flutter/example/lib/superplayer/cgi/playinfo_protocol.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// request handler with tencent fileId
...
...
@@ -32,7 +33,7 @@ class PlayInfoProtocol {
int
code
=
root
[
'code'
];
String
message
=
root
[
'message'
];
String
warning
=
root
[
'warning'
];
LogUtils
.
d
(
TAG
,
"_getVodListData,code=
$code
,message=
$message
,warning=
$warning
"
);
LogUtils
.
d
(
TAG
,
"_getVodListData,code=
(
$code
,
${PlayInfoProtocol.GETPLAYINFOV4_ERROR_CODE_MAP[code]}
)
,message=
$message
,warning=
$warning
"
);
if
(
code
!=
0
)
{
onError
(
code
,
message
);
return
;
...
...
@@ -66,7 +67,7 @@ class PlayInfoProtocol {
return
null
;
}
String
makeQueryString
(
String
?
pcfg
,
String
?
psign
,
String
?
content
)
{
static
String
makeQueryString
(
String
?
pcfg
,
String
?
psign
,
String
?
content
)
{
String
result
=
""
;
if
(
null
!=
pcfg
)
{
result
+=
"pcfg=
$pcfg
&"
;
...
...
@@ -137,4 +138,24 @@ class PlayInfoProtocol {
String
?
getDRMType
()
{
return
null
==
_playInfoParser
?
null
:
_playInfoParser
?.
drmType
;
}
// getplayinfo/v4错误码
// http状态码 200 403
// 403一般鉴权信息不通过或者请求不合法
// 状态码为200的时候才会有http body
// code错误码[1000-2000)请求有问题,
// code错误码[2000-3000)服务端错误,可发起重试
static
Map
<
int
,
String
>
GETPLAYINFOV4_ERROR_CODE_MAP
=
{
0
:
'success'
,
1001
:
'文件不存在'
,
1002
:
'试看时长不合法'
,
1003
:
'pcfg不唯一'
,
1004
:
'license过期'
,
1005
:
'没有自适应码流'
,
1006
:
'请求格式不合法'
,
1007
:
'用户存在'
,
1008
:
'没带防盗链信息'
,
1009
:
'psign检查失败'
,
1010
:
'其他错误'
,
2001
:
'内部错误'
,
};
}
Flutter/example/lib/superplayer/cgi/super_vod_data_loader.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// request data handler
...
...
@@ -13,8 +14,11 @@ class SuperVodDataLoader {
String
field
=
model
.
videoId
!=
null
?
(
model
.
videoId
as
SuperPlayerVideoId
).
fileId
:
""
;
String
psign
=
model
.
videoId
!=
null
?
(
model
.
videoId
as
SuperPlayerVideoId
).
psign
:
""
;
var
url
=
_BASE_URL
+
"/
$appId
/
$field
"
;
var
query
=
makeQueryString
(
null
,
null
,
-
1
,
null
);
var
query
=
PlayInfoProtocol
.
makeQueryString
(
null
,
psign
,
null
);
if
(
query
!=
null
)
{
url
=
url
+
"?"
+
query
;
}
...
...
@@ -29,7 +33,7 @@ class SuperVodDataLoader {
int
code
=
root
[
'code'
];
String
message
=
root
[
'message'
];
String
warning
=
root
[
'warning'
];
LogUtils
.
d
(
TAG
,
"_getVodListData,code=
$code
,message=
$message
,warning=
$warning
"
);
LogUtils
.
d
(
TAG
,
"_getVodListData,code=
(
$code
,
${PlayInfoProtocol.GETPLAYINFOV4_ERROR_CODE_MAP[code]}
)
,message=
$message
,warning=
$warning
"
);
if
(
code
!=
0
)
{
return
;
}
...
...
@@ -80,26 +84,4 @@ class SuperVodDataLoader {
model
.
title
=
newTitle
;
}
}
/// make fileId request url
String
makeQueryString
(
String
?
timeout
,
String
?
us
,
int
exper
,
String
?
sign
)
{
var
str
=
new
StringBuffer
();
if
(
timeout
!=
null
)
{
str
.
write
(
"t="
+
timeout
+
"&"
);
}
if
(
us
!=
null
)
{
str
.
write
(
"us="
+
us
+
"&"
);
}
if
(
sign
!=
null
)
{
str
.
write
(
"sign="
+
sign
+
"&"
);
}
if
(
exper
>=
0
)
{
str
.
write
(
"exper=
$exper
"
+
"&"
);
}
String
result
=
str
.
toString
();
if
(
result
.
length
>
1
)
{
result
=
result
.
substring
(
0
,
result
.
length
-
1
);
}
return
result
;
}
}
Flutter/example/lib/superplayer/common/color_resource.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// colors resource
class
ColorResource
{
static
const
COLOR_MAIN_THEME
=
0xFFFF4C58
;
static
const
COLOR_GRAY
=
0xFFBBBBBB
;
static
const
COLOR_TRANS_BLACK
=
0xBB000000
;
static
const
COLOR_WHITE
=
0xFFFFFFFF
;
}
\ No newline at end of file
Flutter/example/lib/superplayer/common/string_resource.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// string resource
...
...
@@ -10,4 +11,9 @@ class StringResource {
static
const
QUALITY_FHD2
=
"超清"
;
static
const
QUALITY_2K
=
"2K"
;
static
const
QUALITY_4K
=
"4k"
;
static
const
VOICE_LABEL
=
"声音"
;
static
const
BRIGHTNESS_LABEL
=
"亮度"
;
static
const
MULITIPE_SPEED_PLAY_LABEL
=
"多倍速播放"
;
static
const
HARDWARE_ACCE_LABEL
=
"硬件加速"
;
}
Flutter/example/lib/superplayer/common/theme_resource.dart
0 → 100644
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// 样式资源
class
ThemeResource
{
/// 获得通用进度条样式
static
ThemeData
getCommonSliderTheme
()
{
return
ThemeData
(
sliderTheme:
SliderThemeData
(
trackHeight:
2
,
thumbColor:
Color
(
ColorResource
.
COLOR_MAIN_THEME
),
thumbShape:
RoundSliderThumbShape
(
enabledThumbRadius:
4
),
overlayColor:
Colors
.
white
,
overlayShape:
RoundSliderOverlayShape
(
overlayRadius:
10
),
activeTrackColor:
Color
(
ColorResource
.
COLOR_MAIN_THEME
),
inactiveTrackColor:
Color
(
ColorResource
.
COLOR_GRAY
),
));
}
static
TextStyle
getCommonLabelTextStyle
()
{
return
TextStyle
(
fontSize:
14
,
color:
Colors
.
white
);
}
static
TextStyle
getCheckedLabelTextStyle
()
{
return
TextStyle
(
fontSize:
14
,
color:
Color
(
ColorResource
.
COLOR_MAIN_THEME
));
}
static
TextStyle
getCommonTextStyle
()
{
return
TextStyle
(
fontSize:
13
,
color:
Colors
.
white
);
}
static
TextStyle
getCheckedTextStyle
()
{
return
TextStyle
(
fontSize:
13
,
color:
Color
(
ColorResource
.
COLOR_MAIN_THEME
));
}
}
Flutter/example/lib/superplayer/demo_superplayer_lib.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
library
demo_super_player_lib
;
import
'dart:async'
;
...
...
@@ -8,6 +9,7 @@ import 'dart:math';
import
'package:auto_orientation/auto_orientation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/services.dart'
;
import
'package:super_player/super_player.dart'
;
...
...
@@ -25,5 +27,8 @@ part 'ui/superplayer_bottom_view.dart';
part
'ui/superplayer_quality_view.dart'
;
part
'ui/superplayer_title_view.dart'
;
part
'ui/superplayer_widget.dart'
;
part
'ui/superplayer_cover_view.dart'
;
part
'ui/superplayer_more_view.dart'
;
part
'common/color_resource.dart'
;
part
'common/string_resource.dart'
;
\ No newline at end of file
part
'common/string_resource.dart'
;
part
'common/theme_resource.dart'
;
\ No newline at end of file
Flutter/example/lib/superplayer/model/superplayer_define.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
enum
SuperPlayerState
{
...
...
Flutter/example/lib/superplayer/model/superplayer_model.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
class
PlayInfoStream
{
...
...
Flutter/example/lib/superplayer/superplayer_controller.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// superplayer play controller
class
SuperPlayerController
{
...
...
@@ -32,6 +33,7 @@ class SuperPlayerController {
bool
_isMultiBitrateStream
=
false
;
// 是否是多码流url播放
bool
_changeHWAcceleration
=
false
;
// 切换硬解后接收到第一个关键帧前的标记位
bool
_isFullScreen
=
false
;
bool
_isOpenHWAcceleration
=
true
;
final
BuildContext
_context
;
int
currentDuration
=
0
;
...
...
@@ -42,6 +44,7 @@ class SuperPlayerController {
double
startPos
=
0
;
double
videoWidth
=
0
;
double
videoHeight
=
0
;
double
currentPlayRate
=
1.0
;
SuperPlayerController
(
this
.
_context
)
{
_initVodPlayer
();
...
...
@@ -89,7 +92,16 @@ class SuperPlayerController {
}
break
;
case
TXVodPlayEvent
.
PLAY_EVT_PLAY_LOADING
:
// PLAY_EVT_PLAY_LOADING
_updatePlayerState
(
SuperPlayerState
.
LOADING
);
if
(
playerState
==
SuperPlayerState
.
PAUSE
)
{
_updatePlayerState
(
SuperPlayerState
.
PAUSE
);
}
else
{
_updatePlayerState
(
SuperPlayerState
.
LOADING
);
}
break
;
case
TXVodPlayEvent
.
PLAY_EVT_VOD_LOADING_END
:
if
(
playerState
==
SuperPlayerState
.
LOADING
)
{
_updatePlayerState
(
SuperPlayerState
.
PLAYING
);
}
break
;
case
TXVodPlayEvent
.
PLAY_EVT_PLAY_BEGIN
:
// PLAY_EVT_PLAY_BEGIN
if
(
_needToPause
)
{
...
...
@@ -107,6 +119,7 @@ class SuperPlayerController {
seek
(
_seekPos
);
_changeHWAcceleration
=
false
;
}
_updatePlayerState
(
SuperPlayerState
.
PLAYING
);
_observer
?.
onRcvFirstIframe
();
break
;
...
...
@@ -114,25 +127,19 @@ class SuperPlayerController {
_updatePlayerState
(
SuperPlayerState
.
END
);
break
;
case
TXVodPlayEvent
.
PLAY_EVT_PLAY_PROGRESS
:
dynamic
progress
=
event
[
TXVodPlayEvent
.
EVT_PLAY_PROGRESS
_MS
];
dynamic
duration
=
event
[
TXVodPlayEvent
.
EVT_PLAY_DURATION
_MS
];
if
(
null
!=
progress
)
{
currentDuration
=
(
progress
/
1000
)
.
toInt
();
// 当前时间,转换后的单位 秒
dynamic
progress
=
event
[
TXVodPlayEvent
.
EVT_PLAY_PROGRESS
];
dynamic
duration
=
event
[
TXVodPlayEvent
.
EVT_PLAY_DURATION
];
if
(
null
!=
progress
)
{
currentDuration
=
progress
.
toInt
();
// 当前时间,转换后的单位 秒
}
if
(
null
!=
duration
)
{
videoDuration
=
(
duration
/
1000
)
.
toInt
();
// 总播放时长,转换后的单位 秒
if
(
null
!=
duration
)
{
videoDuration
=
duration
.
toInt
();
// 总播放时长,转换后的单位 秒
}
if
(
videoDuration
!=
0
)
{
_observer
?.
onPlayProgress
(
currentDuration
,
videoDuration
);
}
break
;
}
if
(
eventCode
<
0
)
{
_stopPlay
();
_updatePlayerState
(
SuperPlayerState
.
PAUSE
);
_observer
?.
onError
(
SuperPlayerCode
.
VOD_PLAY_FAIL
,
event
[
TXVodPlayEvent
.
EVT_DESCRIPTION
]);
_addSimpleEvent
(
SuperPlayerViewEvent
.
onSuperPlayerError
);
}
_eventStreamController
.
add
(
event
);
});
_vodPlayerController
?.
onPlayerNetStatusBroadcast
.
listen
((
event
)
{
...
...
@@ -164,10 +171,10 @@ class SuperPlayerController {
void
playWithModel
(
SuperPlayerModel
videoModel
)
{
this
.
videoModel
=
videoModel
;
_playAction
=
videoModel
.
playAction
;
resetPlayer
();
if
(
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_AUTO_PLAY
||
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_PRELOAD
)
{
_playWithModelInner
(
videoModel
);
}
else
{
resetPlayer
();
_observer
?.
onNewVideoPlay
();
}
}
...
...
@@ -267,17 +274,17 @@ class SuperPlayerController {
if
(
null
!=
_vodPlayerController
)
{
await
_vodPlayerController
?.
setStartTime
(
startPos
);
if
(
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_PRELOAD
)
{
await
_vodPlayerController
?.
set
Is
AutoPlay
(
isAutoPlay:
false
);
await
_vodPlayerController
?.
setAutoPlay
(
isAutoPlay:
false
);
_playAction
=
SuperPlayerModel
.
PLAY_ACTION_AUTO_PLAY
;
}
else
if
(
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_AUTO_PLAY
||
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_MANUAL_PLAY
)
{
await
_vodPlayerController
?.
set
Is
AutoPlay
(
isAutoPlay:
true
);
await
_vodPlayerController
?.
setAutoPlay
(
isAutoPlay:
true
);
}
String
drmType
=
"plain"
;
if
(
_currentProtocol
!=
null
)
{
LogUtils
.
d
(
TAG
,
"TOKEN:
${_currentProtocol!.getToken()}
"
);
await
_vodPlayerController
?.
setToken
(
_currentProtocol
!.
getToken
());
if
(
_currentProtocol
!.
getDRMType
()
!=
null
&&
_currentProtocol
!.
getDRMType
()!.
isNotEmpty
)
{
if
(
_currentProtocol
!.
getDRMType
()
!=
null
&&
_currentProtocol
!.
getDRMType
()!.
isNotEmpty
)
{
drmType
=
_currentProtocol
!.
getDRMType
()!;
}
}
else
{
...
...
@@ -286,14 +293,14 @@ class SuperPlayerController {
if
(
videoModel
!.
videoId
!=
null
&&
videoModel
!.
appId
!=
0
)
{
Uri
uri
=
Uri
.
parse
(
url
);
String
query
=
uri
.
query
;
if
(
query
==
null
||
query
.
isEmpty
)
{
if
(
query
==
null
||
query
.
isEmpty
)
{
query
=
""
;
}
else
{
query
=
query
+
"&"
;
if
(
query
.
contains
(
"spfileid"
)
||
query
.
contains
(
"spdrmtype"
)
||
query
.
contains
(
"spappid"
))
{
LogUtils
.
d
(
TAG
,
"url contains superplay key.
$query
"
);
}
query
+=
"spfileid=
${videoModel!.videoId!.fileId}
""&spdrmtype=
$drmType
&spappid=
${videoModel!.appId}
"
;
query
+=
"spfileid=
${videoModel!.videoId!.fileId}
"
"&spdrmtype=
$drmType
&spappid=
${videoModel!.appId}
"
;
}
}
LogUtils
.
d
(
TAG
,
"play url:
$url
"
);
...
...
@@ -316,11 +323,11 @@ class SuperPlayerController {
}
/// 继续播放视频
void
resume
()
{
void
resume
()
{
if
(
playerType
==
SuperPlayerType
.
VOD
)
{
_needToResume
=
true
;
if
(
isPrepared
)
{
_vodPlayerController
?.
resume
();
_vodPlayerController
?.
resume
();
}
}
else
{
// todo implements live player
...
...
@@ -413,13 +420,14 @@ class SuperPlayerController {
void
resetPlayer
()
async
{
isPrepared
=
false
;
_needToResume
=
false
;
_needToPause
=
false
;
currentDuration
=
0
;
videoDuration
=
0
;
currentQuality
=
null
;
currentQualiyList
?.
clear
();
_currentProtocol
=
null
;
await
_vodPlayerController
?.
stop
(
isNeedClear:
fals
e
);
await
_vodPlayerController
?.
stop
(
isNeedClear:
tru
e
);
_updatePlayerState
(
SuperPlayerState
.
INIT
);
}
...
...
@@ -435,7 +443,7 @@ class SuperPlayerController {
/// return true : 执行了退出全屏等操作,消耗了返回事件 false:未消耗事件
bool
onBackPress
()
{
if
(
null
!=
_vodPlayerController
&&
_isFullScreen
)
{
if
(
null
!=
_vodPlayerController
&&
_isFullScreen
)
{
_observer
?.
onSysBackPress
();
return
true
;
}
...
...
@@ -454,7 +462,7 @@ class SuperPlayerController {
if
(
videoQuality
.
url
.
isNotEmpty
)
{
// url stream need manual seek
double
currentTime
=
await
_vodPlayerController
!.
getCurrentPlaybackTime
();
await
_vodPlayerController
?.
stop
(
isNeedClear:
tru
e
);
await
_vodPlayerController
?.
stop
(
isNeedClear:
fals
e
);
LogUtils
.
d
(
TAG
,
"onQualitySelect quality.url:
${videoQuality.url}
"
);
await
_vodPlayerController
?.
setStartTime
(
currentTime
);
await
_vodPlayerController
?.
startPlay
(
videoQuality
.
url
);
...
...
@@ -476,7 +484,7 @@ class SuperPlayerController {
bool
?
isPlaying
=
await
_vodPlayerController
?.
isPlaying
();
// resume when not playing.if isPlaying is null,not resume
if
(!(
isPlaying
??
true
))
{
_vodPlayerController
?.
resume
();
resume
();
}
}
else
{
// todo implements live player
...
...
@@ -491,6 +499,7 @@ class SuperPlayerController {
/// 开关硬解编码播放
Future
<
void
>
enableHardwareDecode
(
bool
enable
)
async
{
_isOpenHWAcceleration
=
enable
;
if
(
playerType
==
SuperPlayerType
.
VOD
)
{
if
(
null
!=
_vodPlayerController
)
{
await
_vodPlayerController
?.
enableHardwareDecode
(
enable
);
...
...
@@ -512,6 +521,11 @@ class SuperPlayerController {
}
}
Future
<
void
>
setPlayRate
(
double
rate
)
async
{
currentPlayRate
=
rate
;
_vodPlayerController
?.
setRate
(
rate
);
}
/// 获得当前播放器状态
SuperPlayerState
getPlayerState
()
{
return
playerState
;
...
...
Flutter/example/lib/superplayer/superplayer_observer.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// superplayer's bridge between widget and controller
...
...
Flutter/example/lib/superplayer/tools/video_quality_utils.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// video quality utils
...
...
Flutter/example/lib/superplayer/ui/superplayer_bottom_view.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// slider
...
...
@@ -123,16 +124,7 @@ class _VideoBottomViewState extends State<VideoBottomView> {
Widget
_getSlider
()
{
return
Expanded
(
child:
Theme
(
data:
ThemeData
(
sliderTheme:
SliderThemeData
(
trackHeight:
2
,
thumbColor:
Color
(
ColorResource
.
COLOR_MAIN_THEME
),
thumbShape:
RoundSliderThumbShape
(
enabledThumbRadius:
4
),
overlayColor:
Colors
.
white
,
overlayShape:
RoundSliderOverlayShape
(
overlayRadius:
10
),
activeTrackColor:
Color
(
ColorResource
.
COLOR_MAIN_THEME
),
inactiveTrackColor:
Color
(
ColorResource
.
COLOR_GRAY
),
)),
data:
ThemeResource
.
getCommonSliderTheme
(),
child:
Slider
(
min:
0
,
max:
1
,
...
...
Flutter/example/lib/superplayer/ui/superplayer_cover_view.dart
0 → 100644
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
class
SuperPlayerCoverView
extends
StatefulWidget
{
final
_CoverViewController
_controller
;
SuperPlayerModel
?
videoModel
;
SuperPlayerCoverView
(
this
.
_controller
,
GlobalKey
<
_SuperPlayerCoverViewState
>
key
,
this
.
videoModel
)
:
super
(
key:
key
);
@override
State
<
StatefulWidget
>
createState
()
=>
_SuperPlayerCoverViewState
();
}
class
_SuperPlayerCoverViewState
extends
State
<
SuperPlayerCoverView
>
{
bool
_isShowCover
=
true
;
SuperPlayerModel
?
_videoModel
;
@override
void
initState
()
{
super
.
initState
();
if
(
widget
.
videoModel
!=
null
)
{
_isShowCover
=
true
;
_videoModel
=
widget
.
videoModel
;
}
else
{
_isShowCover
=
false
;
}
}
@override
Widget
build
(
BuildContext
context
)
{
bool
hasCover
=
false
;
String
coverUrl
=
""
;
if
(
null
!=
_videoModel
)
{
SuperPlayerModel
model
=
_videoModel
!;
// custom cover is preferred
if
(
model
.
customeCoverUrl
.
isNotEmpty
)
{
coverUrl
=
model
.
customeCoverUrl
;
hasCover
=
true
;
}
else
if
(
model
.
coverUrl
.
isNotEmpty
)
{
coverUrl
=
model
.
coverUrl
;
hasCover
=
true
;
}
}
return
Visibility
(
visible:
_isShowCover
,
child:
Positioned
.
fill
(
top:
topBottomOffset
,
bottom:
topBottomOffset
,
left:
0
,
right:
0
,
child:
InkWell
(
onDoubleTap:
_onDoubleTapVideo
,
onTap:
_onSingleTapVideo
,
child:
Container
(
child:
hasCover
?
Image
.
network
(
coverUrl
,
fit:
BoxFit
.
cover
,)
:
Container
(),
)
)),
);
}
void
_onDoubleTapVideo
()
{
widget
.
_controller
.
onDoubleTapVideo
();
}
void
_onSingleTapVideo
()
{
widget
.
_controller
.
onSingleTapVideo
();
}
void
showCover
(
SuperPlayerModel
model
)
{
setState
(()
{
_videoModel
=
model
;
_isShowCover
=
true
;
});
}
void
hideCover
()
{
setState
(()
{
_isShowCover
=
false
;
});
}
}
class
_CoverViewController
{
Function
onDoubleTapVideo
;
Function
onSingleTapVideo
;
_CoverViewController
(
this
.
onDoubleTapVideo
,
this
.
onSingleTapVideo
);
}
Flutter/example/lib/superplayer/ui/superplayer_more_view.dart
0 → 100644
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
typedef
BoolFunction
=
bool
Function
();
typedef
DoubleFunction
=
double
Function
();
/// 超级播放器更多菜单
class
SuperPlayerMoreView
extends
StatefulWidget
{
_MoreViewController
controller
;
SuperPlayerMoreView
(
this
.
controller
,
{
Key
?
key
})
:
super
(
key:
key
);
@override
State
<
StatefulWidget
>
createState
()
=>
_SuperPlayerMoreViewState
();
}
class
_SuperPlayerMoreViewState
extends
State
<
SuperPlayerMoreView
>
{
double
_currentBrightness
=
0.01
;
double
_currentVolumn
=
0
;
bool
_isShowMoreView
=
false
;
bool
_isOpenAccelerate
=
true
;
String
_currentRate
=
""
;
Map
<
String
,
double
>
playRateStr
=
{
"1.0x"
:
1.0
,
"1.25x"
:
1.25
,
"1.5x"
:
1.5
,
"2.0x"
:
2.0
};
@override
void
initState
()
{
super
.
initState
();
double
playerPlayRate
=
widget
.
controller
.
getPlayRate
();
for
(
String
rateStr
in
playRateStr
.
keys
)
{
if
(
playerPlayRate
==
playRateStr
[
rateStr
])
{
_currentRate
=
rateStr
;
break
;
}
}
// if not found in playRateStr,set 1.0
if
(
_currentRate
.
isEmpty
)
{
_currentRate
=
playRateStr
.
keys
.
first
;
}
_isOpenAccelerate
=
widget
.
controller
.
getAccelerateIsOpen
();
// regist system volume changed event
SuperPlayerPlugin
.
instance
.
onEventBroadcast
.
listen
((
event
)
{
int
code
=
event
[
"event"
];
if
(
code
==
TXVodPlayEvent
.
EVENT_VOLUME_CHANGED
)
{
refreshVolume
();
}
});
_initData
();
}
void
refreshVolume
()
async
{
_currentVolumn
=
await
SuperPlayerPlugin
.
getSystemVolume
();
setState
(()
{});
}
void
_initData
()
async
{
double
tempBrightness
=
await
SuperPlayerPlugin
.
getBrightness
();
if
(
tempBrightness
==
-
1
)
{
_onChangeBrightness
(
1
);
}
else
{
_currentBrightness
=
tempBrightness
;
}
_currentVolumn
=
await
SuperPlayerPlugin
.
getSystemVolume
();
setState
(()
{});
}
@override
Widget
build
(
BuildContext
context
)
{
return
Visibility
(
visible:
_isShowMoreView
,
child:
Positioned
(
right:
0
,
bottom:
0
,
top:
0
,
child:
Container
(
height:
double
.
infinity
,
width:
320
,
padding:
EdgeInsets
.
only
(
left:
15
,
right:
20
,
top:
15
,
bottom:
15
),
decoration:
BoxDecoration
(
color:
Color
(
ColorResource
.
COLOR_TRANS_BLACK
)),
child:
Center
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
_getVolumeWidget
(),
_getBrightnessWidget
(),
_getPlayRateWidget
(),
_getSwitchHardwareWidget
(),
],
),
)),
));
}
Widget
_getSwitchHardwareWidget
()
{
return
Container
(
margin:
EdgeInsets
.
only
(
top:
10
,
bottom:
10
),
child:
Row
(
children:
[
Text
(
StringResource
.
HARDWARE_ACCE_LABEL
,
textAlign:
TextAlign
.
center
,
style:
ThemeResource
.
getCommonLabelTextStyle
(),
),
Switch
(
activeColor:
Color
(
ColorResource
.
COLOR_MAIN_THEME
),
value:
_isOpenAccelerate
,
onChanged:
_onChangeAccelerate
)
],
),
);
}
Widget
_getPlayRateWidget
()
{
List
<
Widget
>
playRateChild
=
[
Text
(
StringResource
.
MULITIPE_SPEED_PLAY_LABEL
,
textAlign:
TextAlign
.
center
,
style:
ThemeResource
.
getCommonLabelTextStyle
(),
)
];
for
(
String
rateStr
in
playRateStr
.
keys
)
{
playRateChild
.
add
(
Container
(
padding:
EdgeInsets
.
only
(
left:
5
,
right:
5
),
child:
InkWell
(
onTap:
()
=>
_onChangePlayRate
(
rateStr
),
child:
Text
(
rateStr
,
textAlign:
TextAlign
.
center
,
style:
rateStr
==
_currentRate
?
ThemeResource
.
getCheckedLabelTextStyle
()
:
ThemeResource
.
getCommonLabelTextStyle
(),
),
),
));
}
return
Container
(
margin:
EdgeInsets
.
only
(
top:
10
,
bottom:
10
),
child:
Row
(
children:
playRateChild
,
),
);
}
Widget
_getBrightnessWidget
()
{
return
Container
(
margin:
EdgeInsets
.
only
(
top:
10
,
bottom:
10
),
child:
Row
(
children:
[
Text
(
StringResource
.
BRIGHTNESS_LABEL
,
textAlign:
TextAlign
.
center
,
style:
ThemeResource
.
getCommonLabelTextStyle
(),
),
Image
(
width:
30
,
height:
30
,
image:
AssetImage
(
"images/superplayer_ic_light_min.png"
)),
Expanded
(
child:
Theme
(
data:
ThemeResource
.
getCommonSliderTheme
(),
child:
Slider
(
min:
0
,
max:
1
,
value:
_currentBrightness
,
onChanged:
_onChangeBrightness
,
)),
),
Image
(
width:
30
,
height:
30
,
image:
AssetImage
(
"images/superplayer_ic_light_max.png"
)),
]),
);
}
Widget
_getVolumeWidget
()
{
return
Container
(
margin:
EdgeInsets
.
only
(
top:
10
,
bottom:
10
),
child:
Row
(
children:
[
Text
(
StringResource
.
VOICE_LABEL
,
textAlign:
TextAlign
.
center
,
style:
ThemeResource
.
getCommonLabelTextStyle
(),
),
Image
(
width:
30
,
height:
30
,
image:
AssetImage
(
"images/superplayer_ic_volume_min.png"
)),
Expanded
(
child:
Theme
(
data:
ThemeResource
.
getCommonSliderTheme
(),
child:
Slider
(
min:
0
,
max:
1
,
value:
_currentVolumn
,
onChanged:
_onChangeVolume
,
)),
),
Image
(
width:
30
,
height:
30
,
image:
AssetImage
(
"images/superplayer_ic_volume_max.png"
)),
],
),
);
}
void
_onChangePlayRate
(
String
rateKey
)
{
if
(
_currentRate
!=
rateKey
)
{
setState
(()
{
_currentRate
=
rateKey
;
});
double
rate
=
playRateStr
[
_currentRate
]!;
widget
.
controller
.
onChangedPlayRate
(
rate
);
}
}
void
_onChangeBrightness
(
double
value
)
{
if
(
_currentBrightness
!=
value
)
{
setState
(()
{
_currentBrightness
=
value
;
});
SuperPlayerPlugin
.
setBrightness
(
value
);
}
}
void
_onChangeVolume
(
double
value
)
{
if
(
_currentVolumn
!=
value
)
{
setState
(()
{
_currentVolumn
=
value
;
});
SuperPlayerPlugin
.
setSystemVolume
(
value
);
}
}
void
_onChangeAccelerate
(
bool
value
)
{
if
(
value
!=
_isOpenAccelerate
)
{
setState
(()
{
_isOpenAccelerate
=
value
;
});
widget
.
controller
.
siwtchAccelerate
(
value
);
}
}
void
toggleShowMoreView
()
{
setState
(()
{
_isShowMoreView
=
!
_isShowMoreView
;
});
}
void
hideShowMoreView
()
{
if
(
_isShowMoreView
)
{
setState
(()
{
_isShowMoreView
=
false
;
});
}
}
}
class
_MoreViewController
{
BoolFunction
getAccelerateIsOpen
;
DoubleFunction
getPlayRate
;
Function
(
bool
value
)
siwtchAccelerate
;
Function
(
double
playRate
)
onChangedPlayRate
;
_MoreViewController
(
this
.
getAccelerateIsOpen
,
this
.
getPlayRate
,
this
.
siwtchAccelerate
,
this
.
onChangedPlayRate
);
}
Flutter/example/lib/superplayer/ui/superplayer_quality_view.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
class
QualityListView
extends
StatefulWidget
{
...
...
@@ -48,8 +49,8 @@ class _QualityListViewState extends State<QualityListView> {
_qualityList
![
index
].
title
,
textAlign:
TextAlign
.
center
,
style:
_currentQuality
==
_qualityList
![
index
]
?
T
extStyle
(
fontSize:
12
,
color:
Color
(
ColorResource
.
COLOR_MAIN_THEME
)
)
:
T
extStyle
(
fontSize:
12
,
color:
Colors
.
white
),
?
T
hemeResource
.
getCheckedTextStyle
(
)
:
T
hemeResource
.
getCommonTextStyle
(
),
),
),
);
...
...
Flutter/example/lib/superplayer/ui/superplayer_title_view.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
class
_VideoTitleView
extends
StatefulWidget
{
final
String
_title
;
final
_VideoTitleController
_controller
;
final
bool
initIsFullScreen
;
_VideoTitleView
(
this
.
_controller
,
this
.
_title
,
GlobalKey
<
_VideoTitleViewState
>
key
):
super
(
key:
key
);
_VideoTitleView
(
this
.
_controller
,
this
.
initIsFullScreen
,
this
.
_title
,
GlobalKey
<
_VideoTitleViewState
>
key
)
:
super
(
key:
key
);
@override
State
<
StatefulWidget
>
createState
()
=>
_VideoTitleViewState
();
}
class
_VideoTitleViewState
extends
State
<
_VideoTitleView
>
{
String
_title
=
""
;
bool
_isFullScreen
=
false
;
@override
void
initState
()
{
super
.
initState
();
_title
=
widget
.
_title
;
_isFullScreen
=
widget
.
initIsFullScreen
;
}
@override
...
...
@@ -39,26 +43,49 @@ class _VideoTitleViewState extends State<_VideoTitleView> {
Text
(
_title
,
style:
TextStyle
(
fontSize:
11
,
color:
Colors
.
white
),
)
),
Expanded
(
child:
SizedBox
()),
Visibility
(
visible:
_isFullScreen
,
child:
InkWell
(
onTap:
_onTapMore
,
child:
Image
(
width:
30
,
height:
30
,
image:
AssetImage
(
"images/superplayer_ic_vod_more_normal.png"
),
),
))
],
),
);
}
void
_onTapMore
()
{
widget
.
_controller
.
_onTapMore
();
}
void
_onTapBackBtn
()
{
widget
.
_controller
.
_onTapBack
();
}
void
updateTitle
(
String
name
)
{
if
(
mounted
)
{
if
(
mounted
)
{
setState
(()
{
_title
=
name
;
});
}
}
void
updateFullScreen
(
bool
showFullScreen
)
{
setState
(()
{
_isFullScreen
=
showFullScreen
;
});
}
}
class
_VideoTitleController
{
Function
_onTapBack
;
_VideoTitleController
(
this
.
_onTapBack
);
}
\ No newline at end of file
Function
_onTapMore
;
_VideoTitleController
(
this
.
_onTapBack
,
this
.
_onTapMore
);
}
Flutter/example/lib/superplayer/ui/superplayer_widget.dart
浏览文件 @
83a8f6a8
差异被折叠。
点击展开。
Flutter/example/lib/ui/demo_bitrate_checkbox.dart
浏览文件 @
83a8f6a8
import
'package:flutter/cupertino.dart'
;
// Copyright (c) 2022 Tencent. All rights reserved.
import
'package:flutter/material.dart'
;
import
'dart:async'
;
typedef
void
TestBitrateCheckboxFinishCallback
(
int
value
);
...
...
Flutter/example/lib/ui/demo_define.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'package:flutter/material.dart'
;
abstract
class
DemoDefine
{
...
...
Flutter/example/lib/ui/demo_expansion_list_item.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/material.dart'
;
...
...
Flutter/example/lib/ui/demo_expansion_panel_list.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'package:flutter/material.dart'
;
import
'demo_define.dart'
;
...
...
Flutter/example/lib/ui/demo_inputdialog.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'package:flutter/material.dart'
;
typedef
void
DemoInputDialogFinishCallback
(
String
url
,
int
appId
,
String
fileId
);
String
url
,
int
appId
,
String
fileId
,
String
pSign
);
class
DemoInputDialog
extends
StatefulWidget
{
String
url
=
""
;
...
...
@@ -10,8 +10,10 @@ class DemoInputDialog extends StatefulWidget {
String
fileId
=
""
;
DemoInputDialogFinishCallback
callback
;
bool
showFileEdited
=
true
;
bool
needPisgn
=
false
;
DemoInputDialog
(
this
.
url
,
this
.
appId
,
this
.
fileId
,
this
.
callback
,
{
bool
showFileEdited
=
true
})
:
super
()
{
this
.
showFileEdited
=
showFileEdited
;}
DemoInputDialog
(
this
.
url
,
this
.
appId
,
this
.
fileId
,
this
.
callback
,
{
bool
showFileEdited
=
true
,
bool
needPisgn
=
false
})
:
super
()
{
this
.
showFileEdited
=
showFileEdited
;
this
.
needPisgn
=
needPisgn
;}
@override
_DemoInputDialogState
createState
()
=>
_DemoInputDialogState
();
...
...
@@ -21,6 +23,7 @@ class _DemoInputDialogState extends State<DemoInputDialog> {
late
TextEditingController
_urlController
;
late
TextEditingController
_appIdController
;
late
TextEditingController
_fileIdController
;
late
TextEditingController
_pSignController
;
@override
void
initState
()
{
...
...
@@ -30,6 +33,7 @@ class _DemoInputDialogState extends State<DemoInputDialog> {
_appIdController
=
TextEditingController
(
text:
widget
.
appId
>
0
?
widget
.
appId
.
toString
()
:
null
);
_fileIdController
=
TextEditingController
(
text:
widget
.
fileId
);
_pSignController
=
TextEditingController
(
text:
""
);
}
_buildActionWidget
(
BuildContext
context
)
{
...
...
@@ -43,7 +47,8 @@ class _DemoInputDialogState extends State<DemoInputDialog> {
_appIdController
.
text
.
isNotEmpty
?
int
.
parse
(
_appIdController
.
text
)
:
0
,
_fileIdController
.
text
);
_fileIdController
.
text
,
_pSignController
.
text
);
},
// 关闭对话框
),
// Padding(padding: EdgeInsets.only(left: 15)),
...
...
@@ -131,6 +136,30 @@ class _DemoInputDialogState extends State<DemoInputDialog> {
},
)),
):
Container
(),
widget
.
needPisgn
?
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
15
)):
Container
(),
widget
.
needPisgn
?
Container
(
color:
Colors
.
white
,
child:
Theme
(
data:
new
ThemeData
(
primaryColor:
Colors
.
green
),
child:
TextField
(
minLines:
1
,
maxLines:
10
,
controller:
_pSignController
,
cursorColor:
Colors
.
green
,
decoration:
InputDecoration
(
enabledBorder:
OutlineInputBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
10.0
)),
borderSide:
BorderSide
(
color:
Colors
.
green
.
withOpacity
(
0.4
),
width:
3.0
)),
focusedBorder:
OutlineInputBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
10.0
)),
borderSide:
BorderSide
(
color:
Colors
.
green
,
width:
4.0
)),
labelText:
"请输入pSign"
,
labelStyle:
TextStyle
(
color:
Colors
.
grey
),
suffixIcon:
IconButton
(
icon:
Icon
(
Icons
.
close
),
onPressed:
()
{
_pSignController
.
clear
();
})),
onChanged:
(
text
)
{
// _fileId = text;
},
)),
):
Container
(),
],
);
}
...
...
Flutter/example/lib/ui/demo_speed_slider.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'package:flutter/material.dart'
;
typedef
void
DemoSpeedSliderFinishCallback
(
...
...
Flutter/example/lib/ui/demo_video_slider_view.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'package:flutter/material.dart'
;
import
'package:super_player/super_player.dart'
;
...
...
Flutter/example/lib/ui/demo_volume_slider.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'package:flutter/material.dart'
;
typedef
void
DemoVolumeSliderFinishCallback
(
...
...
Flutter/example/lib/ui/treePage.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
import
'dart:math'
;
import
'package:flutter/material.dart'
;
...
...
Flutter/example/pubspec.lock
deleted
100644 → 0
浏览文件 @
4ac57839
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.8.2"
auto_orientation:
dependency: "direct main"
description:
name: auto_orientation
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.15.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.4"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_easyloading:
dependency: "direct main"
description:
name: flutter_easyloading
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.5"
flutter_spinkit:
dependency: transitive
description:
name: flutter_spinkit
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.1.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.11"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.7.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
super_player:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "1.0.2"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.3"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
sdks:
dart: ">=2.14.0 <3.0.0"
flutter: ">=2.0.0"
Flutter/example/pubspec.yaml
浏览文件 @
83a8f6a8
...
...
@@ -44,6 +44,11 @@ flutter:
# the material Icons class.
uses-material-design
:
true
assets
:
-
images/superplayer_ic_vod_more_normal.png
-
images/superplayer_ic_light_max.png
-
images/superplayer_ic_light_min.png
-
images/superplayer_ic_volume_max.png
-
images/superplayer_ic_volume_min.png
-
images/superplayer_ic_vod_pause_normal.png
-
images/superplayer_ic_vod_play_normal.png
-
images/superplayer_bottom_shadow.png
...
...
Flutter/ios/Classes/FTXBasePlayer.h
浏览文件 @
83a8f6a8
//
// FTXBasePlayer.h
// super_player
//
// Created by Zhirui Ou on 2021/3/23.
//
// Copyright (c) 2022 Tencent. All rights reserved.
#import <Foundation/Foundation.h>
...
...
Flutter/ios/Classes/FTXBasePlayer.m
浏览文件 @
83a8f6a8
//
// FTXBasePlayer.m
// super_player
//
// Created by Zhirui Ou on 2021/3/23.
//
// Copyright (c) 2022 Tencent. All rights reserved.
#import "FTXBasePlayer.h"
#import <stdatomic.h>
...
...
Flutter/ios/Classes/FTXEvent.h
0 → 100644
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
#ifndef FTXEvent_h
#define FTXEvent_h
// 音频变化事件code
#define EVENT_VOLUME_CHANGED 0x01
#define EVENT_AUDIO_FOCUS_PAUSE 0x02
#define EVENT_AUDIO_FOCUS_PLAY 0x03
#endif
/* FTXEvent_h */
Flutter/ios/Classes/FTXLivePlayer.h
浏览文件 @
83a8f6a8
//
// FTXLivePlayer.h
// super_player
//
// Created by Zhirui Ou on 2021/3/15.
//
// Copyright (c) 2022 Tencent. All rights reserved.
#import <Foundation/Foundation.h>
#import "FTXBasePlayer.h"
...
...
Flutter/ios/Classes/FTXLivePlayer.m
浏览文件 @
83a8f6a8
//
// FTXLivePlayer.m
// super_player
//
// Created by Zhirui Ou on 2021/3/15.
//
// Copyright (c) 2022 Tencent. All rights reserved.
#import "FTXLivePlayer.h"
#import "FTXPlayerEventSinkQueue.h"
...
...
@@ -112,7 +107,6 @@ static const int uninitialized = -1;
[
config
setPlayerPixelFormatType
:
kCVPixelFormatType_32BGRA
];
[
_txLivePlayer
setConfig
:
config
];
[
_txLivePlayer
setVideoProcessDelegate
:
self
];
_txLivePlayer
.
enableHWAcceleration
=
YES
;
}
}
}
...
...
Flutter/ios/Classes/FTXPlayerEventSinkQueue.h
浏览文件 @
83a8f6a8
//
// FTXPlayerEventSink.h
// super_player
//
// Created by Zhirui Ou on 2021/3/16.
//
// Copyright (c) 2022 Tencent. All rights reserved.
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
...
...
Flutter/ios/Classes/FTXPlayerEventSinkQueue.m
浏览文件 @
83a8f6a8
//
// FTXPlayerEventSink.m
// super_player
//
// Created by Zhirui Ou on 2021/3/16.
//
// Copyright (c) 2022 Tencent. All rights reserved./
#import "FTXPlayerEventSinkQueue.h"
...
...
Flutter/ios/Classes/FTXTransformation.h
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
#import <Foundation/Foundation.h>
#import <TXLiteAVSDK_Player/TXLiteAVSDK.h>
...
...
Flutter/ios/Classes/FTXTransformation.m
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
#import <Foundation/Foundation.h>
#import "FTXTransformation.h"
...
...
Flutter/ios/Classes/FTXVodPlayer.h
浏览文件 @
83a8f6a8
//
// FTXVodPlayer.h
// super_player
//
// Created by Zhirui Ou on 2021/3/15.
//
// Copyright (c) 2022 Tencent. All rights reserved.
#import <Foundation/Foundation.h>
#import "FTXBasePlayer.h"
...
...
Flutter/ios/Classes/FTXVodPlayer.m
浏览文件 @
83a8f6a8
//
// FTXVodPlayer.m
// super_player
//
// Created by Zhirui Ou on 2021/3/15.
//
// Copyright (c) 2022 Tencent. All rights reserved.
#import "FTXVodPlayer.h"
#import "FTXPlayerEventSinkQueue.h"
...
...
@@ -14,6 +9,7 @@
#import <Flutter/Flutter.h>
static
const
int
uninitialized
=
-
1
;
static
const
int
CODE_ON_RECEIVE_FIRST_FRAME
=
2003
;
@interface
FTXVodPlayer
()
<
FlutterStreamHandler
,
FlutterTexture
,
TXVodPlayListener
,
TXVideoCustomProcessDelegate
>
...
...
@@ -38,6 +34,9 @@ static const int uninitialized = -1;
id
<
FlutterTextureRegistry
>
_textureRegistry
;
}
BOOL
volatile
isStop
=
false
;
-
(
instancetype
)
initWithRegistrar
:(
id
<
FlutterPluginRegistrar
>
)
registrar
{
if
(
self
=
[
self
init
])
{
...
...
@@ -116,7 +115,6 @@ static const int uninitialized = -1;
if
(
_txVodPlayer
!=
nil
)
{
[
_txVodPlayer
setVideoProcessDelegate
:
self
];
_txVodPlayer
.
enableHWAcceleration
=
YES
;
}
}
}
...
...
@@ -182,6 +180,7 @@ static const int uninitialized = -1;
-
(
BOOL
)
stopPlay
{
if
(
_txVodPlayer
!=
nil
)
{
isStop
=
true
;
return
[
_txVodPlayer
stopPlay
];
}
return
NO
;
...
...
@@ -240,14 +239,13 @@ static const int uninitialized = -1;
-
(
NSArray
*
)
supportedBitrates
{
if
(
_txVodPlayer
!=
nil
)
{
NSArray
*
itemList
=
_txVodPlayer
.
supportedBitrates
;
NSArray
*
itemList
=
[
_txVodPlayer
supportedBitrates
]
;
NSMutableArray
*
bitrates
=
@[].
mutableCopy
;
for
(
TXBitrateItem
*
item
in
itemList
)
{
[
bitrates
addObject
:@{
@"index"
:
@
(
item
.
index
),
@"width"
:
@
(
item
.
width
),
@"height"
:
@
(
item
.
height
),
@"bitrate"
:
@
(
item
.
bitrate
)}];
}
return
bitrates
;
}
return
@[];
}
...
...
@@ -295,7 +293,7 @@ static const int uninitialized = -1;
BOOL
onlyAudio
=
[
args
[
@"onlyAudio"
]
boolValue
];
NSNumber
*
textureId
=
[
self
createPlayer
:
onlyAudio
];
result
(
textureId
);
}
else
if
([
@"set
Is
AutoPlay"
isEqualToString
:
call
.
method
])
{
}
else
if
([
@"setAutoPlay"
isEqualToString
:
call
.
method
])
{
BOOL
isAutoPlay
=
[
args
[
@"isAutoPlay"
]
boolValue
];
[
self
setIsAutoPlay
:
isAutoPlay
];
result
(
nil
);
...
...
@@ -343,8 +341,8 @@ static const int uninitialized = -1;
[
self
setBitrateIndex
:
index
];
result
(
nil
);
}
else
if
([
@"setStartTime"
isEqualToString
:
call
.
method
])
{
//
float startTime = [args[@"startTime"] floatValue];
//
[self setStartTime:startTime];
float
startTime
=
[
args
[
@"startTime"
]
floatValue
];
[
self
setStartTime
:
startTime
];
result
(
nil
);
}
else
if
([
@"setAudioPlayoutVolume"
isEqualToString
:
call
.
method
])
{
int
volume
=
[
args
[
@"volume"
]
intValue
];
...
...
@@ -469,13 +467,21 @@ static const int uninitialized = -1;
(
void
**
)
&
_latestPixelBuffer
))
{
pixelBuffer
=
_latestPixelBuffer
;
}
return
pixelBuffer
;
if
(
isStop
&&
nil
!=
pixelBuffer
)
{
isStop
=
false
;
[
_eventSink
success
:[
FTXVodPlayer
getParamsWithEvent
:
CODE_ON_RECEIVE_FIRST_FRAME
withParams
:@{}]];
}
return
isStop
?
nil
:
pixelBuffer
;
}
#pragma mark - TXVodPlayListener
-
(
void
)
onPlayEvent
:
(
TXVodPlayer
*
)
player
event
:
(
int
)
EvtID
withParam
:
(
NSDictionary
*
)
param
{
// 交给flutter共享纹理处理首帧事件返回时机
if
(
EvtID
==
CODE_ON_RECEIVE_FIRST_FRAME
)
{
return
;
}
[
_eventSink
success
:[
FTXVodPlayer
getParamsWithEvent
:
EvtID
withParams
:
param
]];
}
...
...
@@ -509,7 +515,7 @@ static const int uninitialized = -1;
_lastBuffer
=
CVPixelBufferRetain
(
pixelBuffer
);
CFRetain
(
pixelBuffer
);
}
CVPixelBufferRef
newBuffer
=
pixelBuffer
;
CVPixelBufferRef
old
=
_latestPixelBuffer
;
...
...
Flutter/ios/Classes/SuperPlayerPlugin.h
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
#import <Flutter/Flutter.h>
@interface
SuperPlayerPlugin
:
NSObject
<
FlutterPlugin
>
...
...
Flutter/ios/Classes/SuperPlayerPlugin.m
浏览文件 @
83a8f6a8
差异被折叠。
点击展开。
Flutter/lib/Core/superplayer_plugin.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
SuperPlayer
;
class
SuperPlayerPlugin
{
static
SuperPlayerPlugin
?
_instance
;
static
SuperPlayerPlugin
get
instance
=>
_sharedInstance
();
/// SuperPlayerPlugin单例
static
SuperPlayerPlugin
_sharedInstance
()
{
if
(
_instance
==
null
)
{
_instance
=
SuperPlayerPlugin
.
_internal
();
}
return
_instance
!;
}
final
StreamController
<
Map
<
dynamic
,
dynamic
>>
_eventStreamController
=
StreamController
.
broadcast
();
/// 原生交互,通用事件监听
Stream
<
Map
<
dynamic
,
dynamic
>>
get
onEventBroadcast
=>
_eventStreamController
.
stream
;
SuperPlayerPlugin
.
_internal
()
{
EventChannel
eventChannel
=
EventChannel
(
"cloud.tencent.com/playerPlugin/event"
);
eventChannel
.
receiveBroadcastStream
(
"event"
).
listen
(
_eventHandler
,
onError:
_errorHandler
);
}
_eventHandler
(
event
)
{
if
(
null
==
event
)
{
return
;
}
_eventStreamController
.
add
(
event
);
}
_errorHandler
(
error
)
{}
static
const
MethodChannel
_channel
=
const
MethodChannel
(
'flutter_super_player'
);
static
Future
<
String
?>
get
platformVersion
async
{
...
...
@@ -8,18 +40,22 @@ class SuperPlayerPlugin {
return
version
;
}
/// 创建直播播放器
static
Future
<
int
?>
createLivePlayer
()
async
{
return
await
_channel
.
invokeMethod
(
'createLivePlayer'
);
}
/// 创建点播播放器
static
Future
<
int
?>
createVodPlayer
()
async
{
return
await
_channel
.
invokeMethod
(
'createVodPlayer'
);
}
/// 开关log输出
static
Future
<
int
?>
setConsoleEnabled
(
bool
enabled
)
async
{
return
await
_channel
.
invokeMethod
(
'setConsoleEnabled'
,
{
"enabled"
:
enabled
});
}
/// 释放播放器资源
static
Future
<
int
?>
releasePlayer
(
int
?
playerId
)
async
{
return
await
_channel
.
invokeMethod
(
'releasePlayer'
,
{
"playerId"
:
playerId
});
}
...
...
@@ -38,4 +74,44 @@ class SuperPlayerPlugin {
static
Future
<
void
>
setGlobalLicense
(
String
licenceUrl
,
String
licenceKey
)
async
{
return
await
_channel
.
invokeMethod
(
"setGlobalLicense"
,
{
"licenceUrl"
:
licenceUrl
,
"licenceKey"
:
licenceKey
});
}
/// 设置log输出级别 [TXLogLevel]
static
Future
<
void
>
setLogLevel
(
int
logLevel
)
async
{
return
await
_channel
.
invokeMethod
(
"setLogLevel"
,
{
"logLevel"
:
logLevel
});
}
/// 修改当前界面亮度
static
Future
<
void
>
setBrightness
(
double
brightness
)
async
{
return
await
_channel
.
invokeMethod
(
"setBrightness"
,
{
"brightness"
:
brightness
});
}
/// 恢复当前界面亮度
static
Future
<
void
>
restorePageBrightness
()
async
{
return
await
_channel
.
invokeMethod
(
"setBrightness"
,
{
"brightness"
:
-
1
});
}
/// 获得当前界面亮度 0.0 ~ 1.0
static
Future
<
double
>
getBrightness
()
async
{
return
await
_channel
.
invokeMethod
(
"getBrightness"
);
}
/// 设置当前系统音量,0.0 ~ 1.0
static
Future
<
void
>
setSystemVolume
(
double
volume
)
async
{
return
await
_channel
.
invokeMethod
(
"setSystemVolume"
,
{
"volume"
:
volume
});
}
/// 获得当前系统音量,范围:0.0 ~ 1.0
static
Future
<
double
>
getSystemVolume
()
async
{
return
await
_channel
.
invokeMethod
(
"getSystemVolume"
);
}
/// 释放音频焦点,只用于安卓端
static
Future
<
double
>
abandonAudioFocus
()
async
{
return
await
_channel
.
invokeMethod
(
"abandonAudioFocus"
);
}
/// 请求获得音频焦点,只用于安卓端
static
Future
<
double
>
requestAudioFocus
()
async
{
return
await
_channel
.
invokeMethod
(
"requestAudioFocus"
);
}
}
Flutter/lib/Core/tools/log_utils.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
SuperPlayer
;
/// log print tools
...
...
Flutter/lib/Core/txliveplayer_controller.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
SuperPlayer
;
class
TXLivePlayerController
extends
ChangeNotifier
implements
ValueListenable
<
TXPlayerValue
?>,
TXPlayerController
{
...
...
Flutter/lib/Core/txplayer_controller.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
SuperPlayer
;
abstract
class
TXPlayerController
{
...
...
Flutter/lib/Core/txplayer_define.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
SuperPlayer
;
class
TXPlayerValue
{
...
...
@@ -80,6 +81,12 @@ abstract class TXVodPlayEvent {
static
const
EVT_PLAY_DURATION
=
"EVT_PLAY_DURATION"
;
// 播放总长
static
const
EVT_PLAYABLE_DURATION_MS
=
"EVT_PLAYABLE_DURATION_MS"
;
// 点播可播放时长(毫秒)
static
const
EVT_PLAYABLE_RATE
=
"EVT_PLAYABLE_RATE"
;
//播放速率
/// superplayer plugin volume evnet
static
const
EVENT_VOLUME_CHANGED
=
0x01
;
// 音量变化
static
const
EVENT_AUDIO_FOCUS_PAUSE
=
0x02
;
// 失去音量输出播放焦点 only for android
static
const
EVENT_AUDIO_FOCUS_PLAY
=
0x03
;
// 获得音量输出焦点 only for android
}
abstract
class
TXVodNetEvent
{
...
...
@@ -132,6 +139,16 @@ enum TXPlayerEvent {
progress
// 进度
}
class
TXLogLevel
{
static
const
int
LOG_LEVEL_VERBOSE
=
0
;
// 输出所有级别的log
static
const
int
LOG_LEVEL_DEBUG
=
1
;
// 输出 DEBUG,INFO,WARNING,ERROR 和 FATAL 级别的log
static
const
int
LOG_LEVEL_INFO
=
2
;
// 输出 INFO,WARNNING,ERROR 和 FATAL 级别的log
static
const
int
LOG_LEVEL_WARN
=
3
;
// 输出WARNNING,ERROR 和 FATAL 级别的log
static
const
int
LOG_LEVEL_ERROR
=
4
;
// 输出ERROR 和 FATAL 级别的log
static
const
int
LOG_LEVEL_FATAL
=
5
;
// 只输出FATAL 级别的log
static
const
int
LOG_LEVEL_NULL
=
6
;
// 不输出任何sdk log
}
class
TXPlayerAuthParams
{
int
appId
=
0
;
String
fileId
=
""
;
...
...
Flutter/lib/Core/txplayer_widget.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
SuperPlayer
;
class
TXPlayerVideo
extends
StatefulWidget
{
final
TXPlayerController
controller
;
TXPlayerVideo
({
required
this
.
controller
}):
assert
(
controller
!=
null
);
TXPlayerVideo
({
required
this
.
controller
,
Key
?
key
})
:
super
(
key:
key
)
{
assert
(
controller
!=
null
);
}
@override
_TXPlayerVideoState
createState
()
=>
_
TXPlayerVideoState
();
TXPlayerVideoState
createState
()
=>
TXPlayerVideoState
();
}
class
_
TXPlayerVideoState
extends
State
<
TXPlayerVideo
>
{
class
TXPlayerVideoState
extends
State
<
TXPlayerVideo
>
{
static
const
TAG
=
"TXPlayerVideo"
;
int
_textureId
=
-
1
;
...
...
@@ -18,49 +20,48 @@ class _TXPlayerVideoState extends State<TXPlayerVideo> {
void
initState
()
{
super
.
initState
();
widget
.
controller
.
textureId
.
then
((
val
)
{
setState
(()
{
LogUtils
.
d
(
TAG
,
"_textureId =
$val
"
);
_textureId
=
val
;
});
widget
.
controller
.
textureId
.
then
((
newTextureId
)
{
if
(
_textureId
!=
newTextureId
)
{
setState
(()
{
LogUtils
.
d
(
TAG
,
"_textureId =
$newTextureId
"
);
_textureId
=
newTextureId
;
});
}
});
}
@override
Widget
build
(
BuildContext
context
)
{
if
((
defaultTargetPlatform
==
TargetPlatform
.
android
)
&&
(
widget
.
controller
.
resizeVideoHeight
!
>
0
&&
widget
.
controller
.
resizeVideoWidth
!
>
0
))
{
if
((
defaultTargetPlatform
==
TargetPlatform
.
android
)
&&
(
widget
.
controller
.
resizeVideoHeight
!
>
0
&&
widget
.
controller
.
resizeVideoWidth
!
>
0
))
{
return
_textureId
==
-
1
?
Container
()
:
LayoutBuilder
(
builder:
(
context
,
constrains
)
{
var
viewWidth
=
constrains
.
maxWidth
;
var
viewHeight
=
constrains
.
maxHeight
;
var
videoWidth
=
widget
.
controller
.
resizeVideoWidth
!;
var
videoHeight
=
widget
.
controller
.
resizeVideoHeight
!;
var
viewWidth
=
constrains
.
maxWidth
;
var
viewHeight
=
constrains
.
maxHeight
;
var
videoWidth
=
widget
.
controller
.
resizeVideoWidth
!;
var
videoHeight
=
widget
.
controller
.
resizeVideoHeight
!;
double
left
=
widget
.
controller
.
videoLeft
!
*
viewWidth
/
videoWidth
;
double
top
=
widget
.
controller
.
videoTop
!
*
viewHeight
/
videoHeight
;
double
right
=
widget
.
controller
.
videoRight
!
*
viewWidth
/
videoWidth
;
double
bottom
=
widget
.
controller
.
videoBottom
!
*
viewHeight
/
videoHeight
;
return
Stack
(
children:
[
Positioned
(
top:
top
,
left:
left
,
right:
right
,
bottom:
bottom
,
child:
Texture
(
textureId:
_textureId
,
)
)
],
);
});
}
else
{
double
left
=
widget
.
controller
.
videoLeft
!
*
viewWidth
/
videoWidth
;
double
top
=
widget
.
controller
.
videoTop
!
*
viewHeight
/
videoHeight
;
double
right
=
widget
.
controller
.
videoRight
!
*
viewWidth
/
videoWidth
;
double
bottom
=
widget
.
controller
.
videoBottom
!
*
viewHeight
/
videoHeight
;
return
Stack
(
children:
[
Positioned
(
top:
top
,
left:
left
,
right:
right
,
bottom:
bottom
,
child:
Texture
(
textureId:
_textureId
)
)
],
);
});
}
else
{
return
_textureId
==
-
1
?
Container
()
:
Texture
(
textureId:
_textureId
,
);
:
Texture
(
textureId:
_textureId
);
}
}
}
Flutter/lib/Core/txvodplayer_config.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
SuperPlayer
;
/// TXVodPlayer config
...
...
Flutter/lib/Core/txvodplayer_controller.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
part of
SuperPlayer
;
class
TXVodPlayerController
extends
ChangeNotifier
implements
ValueListenable
<
TXPlayerValue
?>,
TXPlayerController
{
...
...
@@ -145,7 +146,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
return
result
==
0
;
}
/// 通过field播放视频
/// 通过fi
l
eld播放视频
/// @params : TXPlayerAuthParams
/// return 是否播放成功
Future
<
bool
>
startPlayWithParams
(
TXPlayerAuthParams
params
)
async
{
...
...
@@ -176,10 +177,10 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
}
/// 设置是否自动播放
Future
<
void
>
set
Is
AutoPlay
({
bool
?
isAutoPlay
})
async
{
Future
<
void
>
setAutoPlay
({
bool
?
isAutoPlay
})
async
{
if
(
_isNeedDisposed
)
return
;
await
_initPlayer
.
future
;
await
_channel
.
invokeMethod
(
"set
Is
AutoPlay"
,
{
"isAutoPlay"
:
isAutoPlay
??
false
});
await
_channel
.
invokeMethod
(
"setAutoPlay"
,
{
"isAutoPlay"
:
isAutoPlay
??
false
});
}
/// 停止播放
...
...
@@ -394,14 +395,6 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
notifyListeners
();
}
Future
<
void
>
_switchScreenIOS
(
bool
toFullScreen
)
async
{
if
(
toFullScreen
)
{
await
_channel
.
invokeMethod
(
"orientationToLandscape"
);
}
else
{
await
_channel
.
invokeMethod
(
"orientationToPortrait"
);
}
}
double
?
resizeVideoWidth
=
0
;
double
?
resizeVideoHeight
=
0
;
double
?
videoLeft
=
0
;
...
...
Flutter/lib/super_player.dart
浏览文件 @
83a8f6a8
// Copyright (c) 2022 Tencent. All rights reserved.
library
SuperPlayer
;
import
'dart:async'
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论