mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-10 21:11:27 +08:00
10
lib/models/common/video/source_type.dart
Normal file
10
lib/models/common/video/source_type.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
enum SourceType {
|
||||
normal(-1),
|
||||
archive(1),
|
||||
watchLater(2),
|
||||
fav(3),
|
||||
playlist(3);
|
||||
|
||||
final int mediaType;
|
||||
const SourceType(this.mediaType);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:PiliPlus/http/fav.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/fav_order_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/source_type.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_detail/data.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_detail/media.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_folder/list.dart';
|
||||
@@ -165,7 +166,7 @@ class FavDetailController
|
||||
arguments: {
|
||||
'videoItem': element,
|
||||
'heroTag': Utils.makeHeroTag(element.bvid),
|
||||
'sourceType': 'fav',
|
||||
'sourceType': SourceType.fav,
|
||||
'mediaId': folderInfo.id,
|
||||
'oid': element.id,
|
||||
'favTitle': folderInfo.title,
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/http/fav.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/fav_order_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/source_type.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_detail/data.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_detail/media.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_folder/list.dart';
|
||||
@@ -507,7 +508,7 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
||||
arguments: {
|
||||
'videoItem': item,
|
||||
'heroTag': Utils.makeHeroTag(item.bvid),
|
||||
'sourceType': 'fav',
|
||||
'sourceType': SourceType.fav,
|
||||
'mediaId': folderInfo.id,
|
||||
'oid': item.id,
|
||||
'favTitle': folderInfo.title,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:PiliPlus/models/common/fav_order_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/source_type.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_detail/data.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_detail/media.dart';
|
||||
import 'package:PiliPlus/pages/common/common_search_page.dart';
|
||||
@@ -80,7 +81,7 @@ class _FavSearchPageState
|
||||
arguments: {
|
||||
'videoItem': item,
|
||||
'heroTag': Utils.makeHeroTag(item.bvid),
|
||||
'sourceType': 'fav',
|
||||
'sourceType': SourceType.fav,
|
||||
'mediaId': controller.mediaId,
|
||||
'oid': item.id,
|
||||
'favTitle': controller.title,
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/later_view_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/source_type.dart';
|
||||
import 'package:PiliPlus/models_new/later/list.dart';
|
||||
import 'package:PiliPlus/pages/later/controller.dart';
|
||||
import 'package:PiliPlus/pages/later/widgets/video_card_h_later.dart';
|
||||
@@ -92,7 +93,7 @@ class _LaterViewChildPageState extends State<LaterViewChildPage>
|
||||
'videoItem': videoItem,
|
||||
'oid': videoItem.aid,
|
||||
'heroTag': Utils.makeHeroTag(videoItem.bvid),
|
||||
'sourceType': 'watchLater',
|
||||
'sourceType': SourceType.watchLater,
|
||||
'count': _laterController
|
||||
.baseCtr
|
||||
.counts[LaterViewType.all],
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/user.dart';
|
||||
import 'package:PiliPlus/models/common/later_view_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/source_type.dart';
|
||||
import 'package:PiliPlus/models_new/later/data.dart';
|
||||
import 'package:PiliPlus/models_new/later/list.dart';
|
||||
import 'package:PiliPlus/pages/common/multi_select_controller.dart';
|
||||
@@ -219,7 +220,7 @@ class LaterController extends MultiSelectController<LaterData, LaterItemModel> {
|
||||
arguments: {
|
||||
'videoItem': item,
|
||||
'heroTag': Utils.makeHeroTag(item.bvid),
|
||||
'sourceType': 'watchLater',
|
||||
'sourceType': SourceType.watchLater,
|
||||
'count': baseCtr.counts[LaterViewType.all],
|
||||
'favTitle': '稍后再看',
|
||||
'mediaId': accountService.mid,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/models/common/video/source_type.dart';
|
||||
import 'package:PiliPlus/models_new/later/data.dart';
|
||||
import 'package:PiliPlus/models_new/later/list.dart';
|
||||
import 'package:PiliPlus/pages/common/common_search_page.dart';
|
||||
@@ -49,7 +50,7 @@ class _LaterSearchPageState
|
||||
'videoItem': item,
|
||||
'oid': item.aid,
|
||||
'heroTag': Utils.makeHeroTag(item.bvid),
|
||||
'sourceType': 'watchLater',
|
||||
'sourceType': SourceType.watchLater,
|
||||
'count': controller.count,
|
||||
'favTitle': '稍后再看',
|
||||
'mediaId': controller.mid,
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/member.dart';
|
||||
import 'package:PiliPlus/http/search.dart';
|
||||
import 'package:PiliPlus/models/common/member/contribute_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/source_type.dart';
|
||||
import 'package:PiliPlus/models_new/space/space_archive/data.dart';
|
||||
import 'package:PiliPlus/models_new/space/space_archive/episodic_button.dart';
|
||||
import 'package:PiliPlus/models_new/space/space_archive/item.dart';
|
||||
@@ -157,7 +158,7 @@ class MemberVideoCtr
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'heroTag': Utils.makeHeroTag(oid),
|
||||
'sourceType': 'archive',
|
||||
'sourceType': SourceType.archive,
|
||||
'mediaId': seasonId ?? seriesId ?? mid,
|
||||
'oid': oid,
|
||||
'favTitle': '$username: ${title ?? episodicButton.text ?? '播放全部'}',
|
||||
@@ -198,7 +199,7 @@ class MemberVideoCtr
|
||||
arguments: {
|
||||
'videoItem': element,
|
||||
'heroTag': Utils.makeHeroTag(element.bvid),
|
||||
'sourceType': 'archive',
|
||||
'sourceType': SourceType.archive,
|
||||
'mediaId': seasonId ?? seriesId ?? mid,
|
||||
'oid': IdUtils.bv2av(element.bvid!),
|
||||
'favTitle':
|
||||
|
||||
@@ -18,6 +18,7 @@ import 'package:PiliPlus/models/common/sponsor_block/segment_model.dart';
|
||||
import 'package:PiliPlus/models/common/sponsor_block/segment_type.dart';
|
||||
import 'package:PiliPlus/models/common/sponsor_block/skip_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/audio_quality.dart';
|
||||
import 'package:PiliPlus/models/common/video/source_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/subtitle_pref_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/video_decode_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/video_quality.dart';
|
||||
@@ -39,6 +40,7 @@ import 'package:PiliPlus/pages/video/send_danmaku/view.dart';
|
||||
import 'package:PiliPlus/pages/video/widgets/header_control.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/data_source.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/heart_beat_type.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_status.dart';
|
||||
import 'package:PiliPlus/utils/duration_util.dart';
|
||||
import 'package:PiliPlus/utils/id_utils.dart';
|
||||
@@ -234,18 +236,11 @@ class VideoDetailController extends GetxController
|
||||
}
|
||||
|
||||
// 页面来源 稍后再看 收藏夹
|
||||
String sourceType = 'normal';
|
||||
SourceType sourceType = Get.arguments['sourceType'] ?? SourceType.normal;
|
||||
late bool _mediaDesc = false;
|
||||
late final RxList<MediaListItemModel> mediaList = <MediaListItemModel>[].obs;
|
||||
late String watchLaterTitle = '';
|
||||
bool get isPlayAll =>
|
||||
const ['watchLater', 'fav', 'archive', 'playlist'].contains(sourceType);
|
||||
int get _mediaType => switch (sourceType) {
|
||||
'archive' => 1,
|
||||
'watchLater' => 2,
|
||||
'fav' || 'playlist' => 3,
|
||||
_ => -1,
|
||||
};
|
||||
bool get isPlayAll => sourceType != SourceType.normal;
|
||||
|
||||
late dynamic epId = Get.parameters['epId'];
|
||||
late dynamic seasonId = Get.parameters['seasonId'];
|
||||
@@ -274,9 +269,7 @@ class VideoDetailController extends GetxController
|
||||
}
|
||||
}
|
||||
|
||||
sourceType = Get.arguments['sourceType'] ?? 'normal';
|
||||
|
||||
if (sourceType != 'normal') {
|
||||
if (isPlayAll) {
|
||||
watchLaterTitle = Get.arguments['favTitle'];
|
||||
_mediaDesc = Get.arguments['desc'];
|
||||
getMediaList();
|
||||
@@ -308,7 +301,7 @@ class VideoDetailController extends GetxController
|
||||
return;
|
||||
}
|
||||
var res = await UserHttp.getMediaList(
|
||||
type: Get.arguments['mediaType'] ?? _mediaType,
|
||||
type: Get.arguments['mediaType'] ?? sourceType.mediaType,
|
||||
bizId: Get.arguments['mediaId'] ?? -1,
|
||||
ps: 20,
|
||||
direction: isLoadPrevious ? true : false,
|
||||
@@ -392,10 +385,11 @@ class VideoDetailController extends GetxController
|
||||
? () => getMediaList(isLoadPrevious: true)
|
||||
: null,
|
||||
onDelete:
|
||||
sourceType == 'watchLater' ||
|
||||
(sourceType == 'fav' && Get.arguments?['isOwner'] == true)
|
||||
sourceType == SourceType.watchLater ||
|
||||
(sourceType == SourceType.fav &&
|
||||
Get.arguments?['isOwner'] == true)
|
||||
? (item, index) async {
|
||||
if (sourceType == 'watchLater') {
|
||||
if (sourceType == SourceType.watchLater) {
|
||||
var res = await UserHttp.toViewDel(
|
||||
aids: [item.aid],
|
||||
);
|
||||
@@ -1598,7 +1592,7 @@ class VideoDetailController extends GetxController
|
||||
? -1
|
||||
: playedTime!.inSeconds
|
||||
: playedTime!.inSeconds,
|
||||
type: 'status',
|
||||
type: HeartBeatType.status,
|
||||
isManual: true,
|
||||
bvid: bvid,
|
||||
cid: cid.value,
|
||||
|
||||
@@ -772,7 +772,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
Duration(
|
||||
seconds: DurationUtil.parseDuration(matchStr),
|
||||
),
|
||||
type: 'slider',
|
||||
isSeek: false,
|
||||
);
|
||||
} catch (e) {
|
||||
SmartDialog.showToast('跳转失败: $e');
|
||||
|
||||
@@ -16,6 +16,7 @@ import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/data_source.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/data_status.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/heart_beat_type.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_repeat.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_status.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||
@@ -449,8 +450,11 @@ class PlPlayerController {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> seekToIfExists(Duration position, {type = 'seek'}) async {
|
||||
await _instance?.seekTo(position, type: type);
|
||||
static Future<void> seekToIfExists(
|
||||
Duration position, {
|
||||
bool isSeek = true,
|
||||
}) async {
|
||||
await _instance?.seekTo(position, isSeek: isSeek);
|
||||
}
|
||||
|
||||
static double? getVolumeIfExists() {
|
||||
@@ -635,7 +639,7 @@ class PlPlayerController {
|
||||
return shadersDirectory;
|
||||
}
|
||||
|
||||
bool get _isPgc =>
|
||||
late final _isPgc =
|
||||
Get.parameters['type'] == '1' || Get.parameters['type'] == '4';
|
||||
late int superResolutionType = _isPgc ? Pref.superResolutionType : 0;
|
||||
Future<void> setShader([int? type, NativePlayer? pp]) async {
|
||||
@@ -893,7 +897,7 @@ class PlPlayerController {
|
||||
element(event ? PlayerStatus.playing : PlayerStatus.paused);
|
||||
}
|
||||
if (videoPlayerController!.state.position.inSeconds != 0) {
|
||||
makeHeartBeat(positionSeconds.value, type: 'status');
|
||||
makeHeartBeat(positionSeconds.value, type: HeartBeatType.status);
|
||||
}
|
||||
}),
|
||||
videoPlayerController!.stream.completed.listen((event) {
|
||||
@@ -907,7 +911,7 @@ class PlPlayerController {
|
||||
} else {
|
||||
// playerStatus.status.value = PlayerStatus.playing;
|
||||
}
|
||||
makeHeartBeat(positionSeconds.value, type: 'completed');
|
||||
makeHeartBeat(positionSeconds.value, type: HeartBeatType.completed);
|
||||
}),
|
||||
videoPlayerController!.stream.position.listen((event) {
|
||||
_position.value = event;
|
||||
@@ -1014,7 +1018,7 @@ class PlPlayerController {
|
||||
}
|
||||
|
||||
/// 跳转至指定位置
|
||||
Future<void> seekTo(Duration position, {type = 'seek'}) async {
|
||||
Future<void> seekTo(Duration position, {bool isSeek = true}) async {
|
||||
// if (position >= duration.value) {
|
||||
// position = duration.value - const Duration(milliseconds: 100);
|
||||
// }
|
||||
@@ -1028,7 +1032,7 @@ class PlPlayerController {
|
||||
updatePositionSecond();
|
||||
_heartDuration = position.inSeconds;
|
||||
if (duration.value.inSeconds != 0) {
|
||||
if (type != 'slider') {
|
||||
if (isSeek) {
|
||||
/// 拖动进度条调节时,不等待第一帧,防止抖动
|
||||
await _videoPlayerController?.stream.buffer.first;
|
||||
}
|
||||
@@ -1107,7 +1111,7 @@ class PlPlayerController {
|
||||
// repeat为true,将从头播放
|
||||
if (repeat) {
|
||||
// await seekTo(Duration.zero);
|
||||
await seekTo(Duration.zero, type: "slider");
|
||||
await seekTo(Duration.zero, isSeek: false);
|
||||
}
|
||||
|
||||
await _videoPlayerController?.play();
|
||||
@@ -1424,7 +1428,7 @@ class PlPlayerController {
|
||||
// 记录播放记录
|
||||
Future<void> makeHeartBeat(
|
||||
int progress, {
|
||||
type = 'playing',
|
||||
HeartBeatType type = HeartBeatType.playing,
|
||||
bool isManual = false,
|
||||
dynamic bvid,
|
||||
dynamic cid,
|
||||
@@ -1444,13 +1448,13 @@ class PlPlayerController {
|
||||
}
|
||||
bool isComplete =
|
||||
playerStatus.status.value == PlayerStatus.completed ||
|
||||
type == 'completed';
|
||||
type == HeartBeatType.completed;
|
||||
if ((durationSeconds.value - position.value).inMilliseconds > 1000) {
|
||||
isComplete = false;
|
||||
}
|
||||
// 播放状态变化时,更新
|
||||
|
||||
if (type == 'status' || type == 'completed') {
|
||||
if (type == HeartBeatType.status || type == HeartBeatType.completed) {
|
||||
await VideoHttp.heartBeat(
|
||||
bvid: bvid ?? _bvid,
|
||||
cid: cid ?? _cid,
|
||||
|
||||
5
lib/plugin/pl_player/models/heart_beat_type.dart
Normal file
5
lib/plugin/pl_player/models/heart_beat_type.dart
Normal file
@@ -0,0 +1,5 @@
|
||||
enum HeartBeatType {
|
||||
playing,
|
||||
status,
|
||||
completed,
|
||||
}
|
||||
@@ -949,7 +949,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
} else {
|
||||
plPlayerController.seekTo(
|
||||
plPlayerController.sliderPosition.value,
|
||||
type: 'slider',
|
||||
isSeek: false,
|
||||
);
|
||||
}
|
||||
plPlayerController.onChangedSliderEnd();
|
||||
@@ -1769,10 +1769,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
player.state.duration,
|
||||
);
|
||||
plPlayerController
|
||||
..seekTo(
|
||||
result,
|
||||
type: 'slider',
|
||||
)
|
||||
..seekTo(result, isSeek: false)
|
||||
..play();
|
||||
},
|
||||
),
|
||||
@@ -1803,10 +1800,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
player.state.duration,
|
||||
);
|
||||
plPlayerController
|
||||
..seekTo(
|
||||
result,
|
||||
type: 'slider',
|
||||
)
|
||||
..seekTo(result, isSeek: false)
|
||||
..play();
|
||||
},
|
||||
),
|
||||
|
||||
@@ -103,7 +103,7 @@ class BottomControl extends StatelessWidget {
|
||||
..onChangedSlider(duration.inSeconds.toDouble())
|
||||
..seekTo(
|
||||
Duration(seconds: duration.inSeconds),
|
||||
type: 'slider',
|
||||
isSeek: false,
|
||||
);
|
||||
SemanticsService.announce(
|
||||
"${(duration.inSeconds / max * 100).round()}%",
|
||||
|
||||
@@ -46,7 +46,7 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
|
||||
updatePosition: position,
|
||||
),
|
||||
);
|
||||
await PlPlayerController.seekToIfExists(position, type: 'slider');
|
||||
await PlPlayerController.seekToIfExists(position, isSeek: false);
|
||||
// await player.seekTo(position);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:PiliPlus/http/search.dart';
|
||||
import 'package:PiliPlus/models/common/video/source_type.dart';
|
||||
import 'package:PiliPlus/pages/video/reply_reply/view.dart';
|
||||
import 'package:PiliPlus/utils/extension.dart';
|
||||
import 'package:PiliPlus/utils/id_utils.dart';
|
||||
@@ -632,7 +633,7 @@ class PiliScheme {
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'heroTag': Utils.makeHeroTag(bvid),
|
||||
'sourceType': 'playlist',
|
||||
'sourceType': SourceType.playlist,
|
||||
'favTitle': '播放列表',
|
||||
'mediaId': mediaId,
|
||||
'mediaType': 3,
|
||||
|
||||
Reference in New Issue
Block a user