fix: 视频画质加载异常
This commit is contained in:
@ -29,7 +29,7 @@ class PlayUrlModel {
|
|||||||
int? timeLength;
|
int? timeLength;
|
||||||
String? acceptFormat;
|
String? acceptFormat;
|
||||||
List<dynamic>? acceptDesc;
|
List<dynamic>? acceptDesc;
|
||||||
List<dynamic>? acceptQuality;
|
List<int>? acceptQuality;
|
||||||
int? videoCodecid;
|
int? videoCodecid;
|
||||||
String? seekParam;
|
String? seekParam;
|
||||||
String? seekType;
|
String? seekType;
|
||||||
@ -48,7 +48,7 @@ class PlayUrlModel {
|
|||||||
timeLength = json['timelength'];
|
timeLength = json['timelength'];
|
||||||
acceptFormat = json['accept_format'];
|
acceptFormat = json['accept_format'];
|
||||||
acceptDesc = json['accept_description'];
|
acceptDesc = json['accept_description'];
|
||||||
acceptQuality = json['accept_quality'];
|
acceptQuality = json['accept_quality'].map<int>((e) => e as int).toList();
|
||||||
videoCodecid = json['video_codecid'];
|
videoCodecid = json['video_codecid'];
|
||||||
seekParam = json['seek_param'];
|
seekParam = json['seek_param'];
|
||||||
seekType = json['seek_type'];
|
seekType = json['seek_type'];
|
||||||
|
@ -13,40 +13,47 @@ import 'package:pilipala/models/video/reply/item.dart';
|
|||||||
import 'package:pilipala/pages/video/detail/replyReply/index.dart';
|
import 'package:pilipala/pages/video/detail/replyReply/index.dart';
|
||||||
import 'package:pilipala/plugin/pl_player/index.dart';
|
import 'package:pilipala/plugin/pl_player/index.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
|
||||||
class VideoDetailController extends GetxController
|
class VideoDetailController extends GetxController
|
||||||
with GetSingleTickerProviderStateMixin {
|
with GetSingleTickerProviderStateMixin {
|
||||||
int tabInitialIndex = 0;
|
/// 路由传参
|
||||||
TabController? tabCtr;
|
|
||||||
// tabs
|
|
||||||
RxList<String> tabs = <String>['简介', '评论'].obs;
|
|
||||||
|
|
||||||
// 视频aid
|
|
||||||
String bvid = Get.parameters['bvid']!;
|
String bvid = Get.parameters['bvid']!;
|
||||||
int cid = int.parse(Get.parameters['cid']!);
|
int cid = int.parse(Get.parameters['cid']!);
|
||||||
// 视频类型 默认投稿视频
|
String heroTag = Get.arguments['heroTag'];
|
||||||
SearchType videoType = SearchType.video;
|
// 视频详情
|
||||||
|
|
||||||
late PlayUrlModel data;
|
|
||||||
|
|
||||||
Box setting = GStrorage.setting;
|
|
||||||
// 当前画质
|
|
||||||
late VideoQuality currentVideoQa;
|
|
||||||
// 当前音质
|
|
||||||
late AudioQuality currentAudioQa;
|
|
||||||
// 当前解码格式
|
|
||||||
late VideoDecodeFormats currentDecodeFormats;
|
|
||||||
|
|
||||||
// 是否预渲染 骨架屏
|
|
||||||
bool preRender = false;
|
|
||||||
|
|
||||||
// 视频详情 上个页面传入
|
|
||||||
Map videoItem = {};
|
Map videoItem = {};
|
||||||
|
// 视频类型 默认投稿视频
|
||||||
|
SearchType videoType = Get.arguments['videoType'] ?? SearchType.video;
|
||||||
|
|
||||||
|
/// tabs相关配置
|
||||||
|
int tabInitialIndex = 0;
|
||||||
|
late TabController tabCtr;
|
||||||
|
RxList<String> tabs = <String>['简介', '评论'].obs;
|
||||||
|
|
||||||
|
// 请求返回的视频信息
|
||||||
|
late PlayUrlModel data;
|
||||||
// 请求状态
|
// 请求状态
|
||||||
RxBool isLoading = false.obs;
|
RxBool isLoading = false.obs;
|
||||||
|
|
||||||
String heroTag = '';
|
/// 播放器配置 画质 音质 解码格式
|
||||||
|
late VideoQuality currentVideoQa;
|
||||||
|
late AudioQuality currentAudioQa;
|
||||||
|
late VideoDecodeFormats currentDecodeFormats;
|
||||||
|
PlPlayerController plPlayerController = PlPlayerController();
|
||||||
|
// 是否开始自动播放 存在多p的情况下,第二p需要为true
|
||||||
|
RxBool autoPlay = true.obs;
|
||||||
|
// 视频资源是否有效
|
||||||
|
RxBool isEffective = true.obs;
|
||||||
|
// 封面图的展示
|
||||||
|
RxBool isShowCover = true.obs;
|
||||||
|
// 硬解
|
||||||
|
RxBool enableHA = true.obs;
|
||||||
|
|
||||||
|
/// 本地存储
|
||||||
|
Box user = GStrorage.user;
|
||||||
|
Box localCache = GStrorage.localCache;
|
||||||
|
Box setting = GStrorage.setting;
|
||||||
|
|
||||||
int oid = 0;
|
int oid = 0;
|
||||||
// 评论id 请求楼中楼评论使用
|
// 评论id 请求楼中楼评论使用
|
||||||
@ -55,38 +62,27 @@ class VideoDetailController extends GetxController
|
|||||||
ReplyItemModel? firstFloor;
|
ReplyItemModel? firstFloor;
|
||||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
Timer? timer;
|
Timer? timer;
|
||||||
RxString bgCover = ''.obs;
|
|
||||||
Box user = GStrorage.user;
|
|
||||||
Box localCache = GStrorage.localCache;
|
|
||||||
PlPlayerController plPlayerController = PlPlayerController();
|
|
||||||
// 是否开始自动播放 存在多p的情况下,第二p需要为true
|
|
||||||
RxBool autoPlay = true.obs;
|
|
||||||
// 视频资源是否有效
|
|
||||||
RxBool isEffective = true.obs;
|
|
||||||
// 封面图的展示
|
|
||||||
RxBool isShowCover = true.obs;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
if (Get.arguments.isNotEmpty) {
|
Map argMap = Get.arguments;
|
||||||
if (Get.arguments.containsKey('videoItem')) {
|
var keys = argMap.keys.toList();
|
||||||
preRender = true;
|
if (keys.isNotEmpty) {
|
||||||
var args = Get.arguments['videoItem'];
|
if (keys.contains('videoItem')) {
|
||||||
|
var args = argMap['videoItem'];
|
||||||
if (args.pic != null && args.pic != '') {
|
if (args.pic != null && args.pic != '') {
|
||||||
videoItem['pic'] = args.pic;
|
videoItem['pic'] = args.pic;
|
||||||
bgCover.value = args.pic;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Get.arguments.containsKey('pic')) {
|
if (keys.contains('pic')) {
|
||||||
videoItem['pic'] = Get.arguments['pic'];
|
videoItem['pic'] = argMap['pic'];
|
||||||
bgCover.value = Get.arguments['pic'];
|
|
||||||
}
|
}
|
||||||
heroTag = Get.arguments['heroTag'];
|
|
||||||
videoType = Get.arguments['videoType'] ?? SearchType.video;
|
|
||||||
}
|
}
|
||||||
tabCtr = TabController(length: 2, vsync: this);
|
tabCtr = TabController(length: 2, vsync: this);
|
||||||
// queryVideoUrl();
|
autoPlay.value =
|
||||||
|
setting.get(SettingBoxKey.autoPlayEnable, defaultValue: true);
|
||||||
|
enableHA.value = setting.get(SettingBoxKey.enableHA, defaultValue: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
showReplyReplyPanel() {
|
showReplyReplyPanel() {
|
||||||
@ -123,7 +119,6 @@ class VideoDetailController extends GetxController
|
|||||||
data.dash!.video!.where((i) => i.id == currentVideoQa.code).toList();
|
data.dash!.video!.where((i) => i.id == currentVideoQa.code).toList();
|
||||||
VideoItem firstVideo = videoList
|
VideoItem firstVideo = videoList
|
||||||
.firstWhere((i) => i.codecs!.startsWith(currentDecodeFormats.code));
|
.firstWhere((i) => i.codecs!.startsWith(currentDecodeFormats.code));
|
||||||
// String videoUrl = firstVideo.baseUrl!;
|
|
||||||
|
|
||||||
/// 根据currentAudioQa 重新设置audioUrl
|
/// 根据currentAudioQa 重新设置audioUrl
|
||||||
AudioItem firstAudio =
|
AudioItem firstAudio =
|
||||||
@ -147,7 +142,7 @@ class VideoDetailController extends GetxController
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
// 硬解
|
// 硬解
|
||||||
enableHA: true,
|
enableHA: enableHA.value,
|
||||||
autoplay: autoPlay.value,
|
autoplay: autoPlay.value,
|
||||||
seekTo: defaultST,
|
seekTo: defaultST,
|
||||||
duration: Duration(milliseconds: duration),
|
duration: Duration(milliseconds: duration),
|
||||||
@ -180,8 +175,10 @@ class VideoDetailController extends GetxController
|
|||||||
defaultValue: currentHighVideoQa);
|
defaultValue: currentHighVideoQa);
|
||||||
int resVideoQa = currentHighVideoQa;
|
int resVideoQa = currentHighVideoQa;
|
||||||
if (cacheVideoQa <= currentHighVideoQa) {
|
if (cacheVideoQa <= currentHighVideoQa) {
|
||||||
// 如果默认设置的画质比当前可用的低,使用默认值
|
List<int> numbers = data.acceptQuality!
|
||||||
resVideoQa = cacheVideoQa;
|
.where((e) => e <= currentHighVideoQa)
|
||||||
|
.toList();
|
||||||
|
resVideoQa = Utils.findClosestNumber(cacheVideoQa, numbers);
|
||||||
}
|
}
|
||||||
currentVideoQa = VideoQualityCode.fromCode(resVideoQa)!;
|
currentVideoQa = VideoQualityCode.fromCode(resVideoQa)!;
|
||||||
|
|
||||||
@ -208,16 +205,17 @@ class VideoDetailController extends GetxController
|
|||||||
|
|
||||||
/// 优先顺序 设置中指定质量 -> 当前可选的最高质量
|
/// 优先顺序 设置中指定质量 -> 当前可选的最高质量
|
||||||
late AudioItem firstAudio;
|
late AudioItem firstAudio;
|
||||||
|
List audiosList = data.dash!.audio!;
|
||||||
try {
|
try {
|
||||||
if (data.dash!.audio!.isNotEmpty) {
|
if (audiosList.isNotEmpty) {
|
||||||
firstAudio = data.dash!.audio!.first;
|
firstAudio = audiosList.first;
|
||||||
int resultAudioQa = setting.get(SettingBoxKey.defaultAudioQa,
|
int resultAudioQa = setting.get(SettingBoxKey.defaultAudioQa,
|
||||||
defaultValue: data.dash!.audio!.first.id);
|
defaultValue: firstAudio.id);
|
||||||
// 选择最接近的那个音轨
|
// 选择最接近的那个音轨
|
||||||
try {
|
firstAudio = audiosList.firstWhere(
|
||||||
firstAudio =
|
(e) => e.id == resultAudioQa,
|
||||||
data.dash!.audio!.firstWhere((e) => e.id == resultAudioQa);
|
orElse: () => AudioItem(),
|
||||||
} catch (_) {}
|
);
|
||||||
} else {
|
} else {
|
||||||
firstAudio = AudioItem();
|
firstAudio = AudioItem();
|
||||||
}
|
}
|
||||||
|
@ -162,4 +162,20 @@ class Utils {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int findClosestNumber(int target, List<int> numbers) {
|
||||||
|
int minDiff = 127;
|
||||||
|
late int closestNumber;
|
||||||
|
try {
|
||||||
|
for (int number in numbers) {
|
||||||
|
int diff = (number - target).abs();
|
||||||
|
|
||||||
|
if (diff < minDiff) {
|
||||||
|
minDiff = diff;
|
||||||
|
closestNumber = number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
return closestNumber;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user