diff --git a/lib/http/video.dart b/lib/http/video.dart index 4413b44f..af9a3fa1 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -6,6 +6,7 @@ import 'package:pilipala/models/common/reply_type.dart'; import 'package:pilipala/models/model_hot_video_item.dart'; import 'package:pilipala/models/model_rec_video_item.dart'; import 'package:pilipala/models/user/fav_folder.dart'; +import 'package:pilipala/models/video/play/url.dart'; import 'package:pilipala/models/video_detail_res.dart'; /// res.data['code'] == 0 请求正常返回结果 @@ -66,8 +67,9 @@ class VideoHttp { 'avid': avid, // 'bvid': bvid, 'cid': cid, - 'qn': qn ?? 64, - // 'fnval': 16, + // 'qn': qn ?? 80, + // 获取所有格式的视频 + 'fnval': 4048, // 'fnver': '', 'fourk': 1, // 'session': '', @@ -83,7 +85,10 @@ class VideoHttp { // for (var i in res.data['data']['list']) { // list.add(HotVideoItemModel.fromJson(i)); // } - return {'status': true, 'data': res.data['data']}; + return { + 'status': true, + 'data': PlayUrlModel.fromJson(res.data['data']) + }; } else { return {'status': false, 'data': []}; } diff --git a/lib/models/video/play/url.dart b/lib/models/video/play/url.dart new file mode 100644 index 00000000..79b62036 --- /dev/null +++ b/lib/models/video/play/url.dart @@ -0,0 +1,181 @@ +class PlayUrlModel { + PlayUrlModel({ + this.from, + this.result, + this.message, + this.quality, + this.format, + this.timeLength, + this.acceptFormat, + this.acceptDesc, + this.acceptQuality, + this.videoCodecid, + this.seekParam, + this.seekType, + this.dash, + this.supportFormats, + // this.highFormat, + this.lastPlayTime, + this.lastPlayCid, + }); + + String? from; + String? result; + String? message; + int? quality; + String? format; + int? timeLength; + String? acceptFormat; + List? acceptDesc; + List? acceptQuality; + int? videoCodecid; + String? seekParam; + String? seekType; + Dash? dash; + List? supportFormats; + // String? highFormat; + int? lastPlayTime; + int? lastPlayCid; + + PlayUrlModel.fromJson(Map json) { + from = json['from']; + result = json['result']; + message = json['message']; + quality = json['quality']; + format = json['format']; + timeLength = json['timelength']; + acceptFormat = json['accept_format']; + acceptDesc = json['accept_description']; + acceptQuality = json['accept_quality']; + videoCodecid = json['video_codecid']; + seekParam = json['seek_param']; + seekType = json['seek_type']; + dash = Dash.fromJson(json['dash']); + supportFormats = json['support_formats']; + lastPlayTime = json['last_play_time']; + lastPlayCid = json['last_play_cid']; + } +} + +class Dash { + Dash({ + this.duration, + this.minBufferTime, + this.video, + this.audio, + this.dolby, + this.flac, + }); + + int? duration; + double? minBufferTime; + List? video; + List? audio; + Map? dolby; + String? flac; + + Dash.fromJson(Map json) { + duration = json['duration']; + minBufferTime = json['minBufferTime']; + video = json['video'].map((e) => VideoItem.fromJson(e)).toList(); + audio = json['audio'].map((e) => AudioItem.fromJson(e)).toList(); + dolby = json['dolby']; + flac = json['flac'] ?? ''; + } +} + +class VideoItem { + VideoItem({ + this.id, + this.baseUrl, + this.backupUrl, + this.bandWidth, + this.mimeType, + this.codecs, + this.width, + this.height, + this.frameRate, + this.sar, + this.startWithSap, + this.segmentBase, + this.codecid, + }); + + int? id; + String? baseUrl; + String? backupUrl; + int? bandWidth; + String? mimeType; + String? codecs; + int? width; + int? height; + String? frameRate; + String? sar; + int? startWithSap; + Map? segmentBase; + int? codecid; + + VideoItem.fromJson(Map json) { + id = json['id']; + baseUrl = json['baseUrl']; + backupUrl = json['backupUrl'].toList().first; + bandWidth = json['bandWidth']; + mimeType = json['mime_type']; + codecs = json['codecs']; + width = json['width']; + height = json['height']; + frameRate = json['frameRate']; + sar = json['sar']; + startWithSap = json['startWithSap']; + segmentBase = json['segmentBase']; + codecid = json['codecid']; + } +} + +class AudioItem { + AudioItem({ + this.id, + this.baseUrl, + this.backupUrl, + this.bandWidth, + this.mimeType, + this.codecs, + this.width, + this.height, + this.frameRate, + this.sar, + this.startWithSap, + this.segmentBase, + this.codecid, + }); + + int? id; + String? baseUrl; + String? backupUrl; + int? bandWidth; + String? mimeType; + String? codecs; + int? width; + int? height; + String? frameRate; + String? sar; + int? startWithSap; + Map? segmentBase; + int? codecid; + + AudioItem.fromJson(Map json) { + id = json['id']; + baseUrl = json['baseUrl']; + backupUrl = json['backupUrl'].toList().first; + bandWidth = json['bandWidth']; + mimeType = json['mime_type']; + codecs = json['codecs']; + width = json['width']; + height = json['height']; + frameRate = json['frameRate']; + sar = json['sar']; + startWithSap = json['startWithSap']; + segmentBase = json['segmentBase']; + codecid = json['codecid']; + } +} diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index ca0f959b..3e375d27 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -1,10 +1,12 @@ import 'dart:async'; +import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter_meedu_media_kit/meedu_player.dart'; import 'package:get/get.dart'; import 'package:pilipala/http/constants.dart'; import 'package:pilipala/http/video.dart'; +import 'package:pilipala/models/video/play/url.dart'; import 'package:pilipala/models/video/reply/item.dart'; import 'package:pilipala/pages/video/detail/replyReply/index.dart'; @@ -79,11 +81,12 @@ class VideoDetailController extends GetxController { }); } - playerInit(url) { + playerInit(source, audioSource, {Duration defaultST = Duration.zero}) { meeduPlayerController.setDataSource( DataSource( type: DataSourceType.network, - source: url, + source: source, + audioSource: audioSource, httpHeaders: { 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_3_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15', @@ -91,7 +94,8 @@ class VideoDetailController extends GetxController { }, ), autoplay: true, - looping: false + looping: false, + seekTo: defaultST, ); } @@ -108,7 +112,16 @@ class VideoDetailController extends GetxController { // 视频链接 queryVideoUrl() async { var result = await VideoHttp.videoUrl(cid: cid, avid: aid); - var url = result['data']['durl'].first['url']; - playerInit(url); + // log('result: ${result.toString()}'); + if (result['status']) { + PlayUrlModel data = result['data']; + print(data.dash); + + // 指定质量的视频 -> 最高质量的视频 + String videoUrl = data.dash!.video!.first.baseUrl!; + String audioUrl = data.dash!.audio!.first.baseUrl!; + playerInit(videoUrl, audioUrl, + defaultST: Duration(milliseconds: data.lastPlayTime!)); + } } }