mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-16 23:26:14 +08:00
@@ -224,12 +224,18 @@ class VideoHttp {
|
|||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
late PlayUrlModel data;
|
late PlayUrlModel data;
|
||||||
switch (videoType) {
|
switch (videoType) {
|
||||||
case VideoType.ugc || VideoType.pugv:
|
case VideoType.ugc:
|
||||||
data = PlayUrlModel.fromJson(res.data['data']);
|
data = PlayUrlModel.fromJson(res.data['data']);
|
||||||
|
case VideoType.pugv:
|
||||||
|
var result = res.data['data'];
|
||||||
|
data = PlayUrlModel.fromJson(result)
|
||||||
|
..lastPlayTime =
|
||||||
|
result?['play_view_business_info']?['user_status']?['watch_progress']?['current_watch_progress'];
|
||||||
case VideoType.pgc:
|
case VideoType.pgc:
|
||||||
data = PlayUrlModel.fromJson(res.data['result']['video_info'])
|
var result = res.data['result'];
|
||||||
..lastPlayTime = res
|
data = PlayUrlModel.fromJson(result['video_info'])
|
||||||
.data['result']?['play_view_business_info']?['user_status']?['watch_progress']?['current_watch_progress'];
|
..lastPlayTime =
|
||||||
|
result?['play_view_business_info']?['user_status']?['watch_progress']?['current_watch_progress'];
|
||||||
}
|
}
|
||||||
return {'status': true, 'data': data};
|
return {'status': true, 'data': data};
|
||||||
} else {
|
} else {
|
||||||
@@ -639,6 +645,7 @@ class VideoHttp {
|
|||||||
|
|
||||||
// 视频播放进度
|
// 视频播放进度
|
||||||
static Future heartBeat({
|
static Future heartBeat({
|
||||||
|
aid,
|
||||||
bvid,
|
bvid,
|
||||||
cid,
|
cid,
|
||||||
progress,
|
progress,
|
||||||
@@ -647,10 +654,11 @@ class VideoHttp {
|
|||||||
subType,
|
subType,
|
||||||
required VideoType videoType,
|
required VideoType videoType,
|
||||||
}) async {
|
}) async {
|
||||||
|
final isPugv = videoType == VideoType.pugv;
|
||||||
await Request().post(
|
await Request().post(
|
||||||
Api.heartBeat,
|
Api.heartBeat,
|
||||||
queryParameters: {
|
queryParameters: {
|
||||||
'bvid': bvid,
|
if (isPugv) 'aid': ?aid else 'bvid': ?bvid,
|
||||||
'cid': cid,
|
'cid': cid,
|
||||||
'epid': ?epid,
|
'epid': ?epid,
|
||||||
'sid': ?seasonId,
|
'sid': ?seasonId,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ abstract class CommonIntroController extends GetxController {
|
|||||||
|
|
||||||
final Rx<VideoDetailData> videoDetail = VideoDetailData().obs;
|
final Rx<VideoDetailData> videoDetail = VideoDetailData().obs;
|
||||||
|
|
||||||
Future<void> queryVideoIntro();
|
void queryVideoIntro();
|
||||||
|
|
||||||
bool prevPlay();
|
bool prevPlay();
|
||||||
bool nextPlay();
|
bool nextPlay();
|
||||||
|
|||||||
@@ -71,7 +71,11 @@ class HistoryItem extends StatelessWidget {
|
|||||||
PageUtils.viewPgc(epId: item.history.epid);
|
PageUtils.viewPgc(epId: item.history.epid);
|
||||||
} else if (item.history.business == 'cheese') {
|
} else if (item.history.business == 'cheese') {
|
||||||
if (item.uri?.isNotEmpty == true) {
|
if (item.uri?.isNotEmpty == true) {
|
||||||
PageUtils.viewPgcFromUri(item.uri!, isPgc: false);
|
PageUtils.viewPgcFromUri(
|
||||||
|
item.uri!,
|
||||||
|
isPgc: false,
|
||||||
|
aid: item.history.oid,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int? cid =
|
int? cid =
|
||||||
|
|||||||
@@ -1130,6 +1130,7 @@ class VideoDetailController extends GetxController
|
|||||||
: Duration(milliseconds: data.timeLength!)),
|
: Duration(milliseconds: data.timeLength!)),
|
||||||
// 宽>高 水平 否则 垂直
|
// 宽>高 水平 否则 垂直
|
||||||
isVertical: isVertical.value,
|
isVertical: isVertical.value,
|
||||||
|
aid: aid,
|
||||||
bvid: bvid,
|
bvid: bvid,
|
||||||
cid: cid.value,
|
cid: cid.value,
|
||||||
autoplay: autoplay ?? autoPlay.value,
|
autoplay: autoplay ?? autoPlay.value,
|
||||||
@@ -1599,6 +1600,7 @@ class VideoDetailController extends GetxController
|
|||||||
: playedTime!.inSeconds,
|
: playedTime!.inSeconds,
|
||||||
type: HeartBeatType.status,
|
type: HeartBeatType.status,
|
||||||
isManual: true,
|
isManual: true,
|
||||||
|
aid: aid,
|
||||||
bvid: bvid,
|
bvid: bvid,
|
||||||
cid: cid.value,
|
cid: cid.value,
|
||||||
epid: isUgc ? null : epId,
|
epid: isUgc ? null : epId,
|
||||||
|
|||||||
@@ -312,8 +312,8 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
|
|
||||||
hasLater.value = false;
|
hasLater.value = false;
|
||||||
this.cid.value = cid;
|
this.cid.value = cid;
|
||||||
queryVideoIntro();
|
|
||||||
queryOnlineTotal();
|
queryOnlineTotal();
|
||||||
|
queryVideoIntro(episode as EpisodeItem);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('pgc onChangeEpisode: $e');
|
debugPrint('pgc onChangeEpisode: $e');
|
||||||
}
|
}
|
||||||
@@ -467,8 +467,8 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> queryVideoIntro() async {
|
void queryVideoIntro([EpisodeItem? episode]) {
|
||||||
final episode = pgcItem.episodes!.firstWhere((e) => e.cid == cid.value);
|
episode ??= pgcItem.episodes!.firstWhere((e) => e.cid == cid.value);
|
||||||
videoPlayerServiceHandler.onVideoDetailChange(
|
videoPlayerServiceHandler.onVideoDetailChange(
|
||||||
episode,
|
episode,
|
||||||
cid.value,
|
cid.value,
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ class PlPlayerController {
|
|||||||
final bool _listenersInitialized = false;
|
final bool _listenersInitialized = false;
|
||||||
|
|
||||||
// 记录历史记录
|
// 记录历史记录
|
||||||
|
int? _aid;
|
||||||
String _bvid = '';
|
String _bvid = '';
|
||||||
int _cid = 0;
|
int _cid = 0;
|
||||||
dynamic _epid;
|
dynamic _epid;
|
||||||
@@ -528,6 +529,7 @@ class PlPlayerController {
|
|||||||
// 方向
|
// 方向
|
||||||
bool? isVertical,
|
bool? isVertical,
|
||||||
// 记录历史记录
|
// 记录历史记录
|
||||||
|
int? aid,
|
||||||
String bvid = '',
|
String bvid = '',
|
||||||
int cid = 0,
|
int cid = 0,
|
||||||
dynamic epid,
|
dynamic epid,
|
||||||
@@ -553,6 +555,7 @@ class PlPlayerController {
|
|||||||
dataStatus.status.value = DataStatus.loading;
|
dataStatus.status.value = DataStatus.loading;
|
||||||
// 初始化全屏方向
|
// 初始化全屏方向
|
||||||
_isVertical = isVertical ?? false;
|
_isVertical = isVertical ?? false;
|
||||||
|
_aid = aid;
|
||||||
_bvid = bvid;
|
_bvid = bvid;
|
||||||
_cid = cid;
|
_cid = cid;
|
||||||
_epid = epid;
|
_epid = epid;
|
||||||
@@ -1440,6 +1443,7 @@ class PlPlayerController {
|
|||||||
int progress, {
|
int progress, {
|
||||||
HeartBeatType type = HeartBeatType.playing,
|
HeartBeatType type = HeartBeatType.playing,
|
||||||
bool isManual = false,
|
bool isManual = false,
|
||||||
|
dynamic aid,
|
||||||
dynamic bvid,
|
dynamic bvid,
|
||||||
dynamic cid,
|
dynamic cid,
|
||||||
dynamic epid,
|
dynamic epid,
|
||||||
@@ -1467,6 +1471,7 @@ class PlPlayerController {
|
|||||||
|
|
||||||
if (type == HeartBeatType.status || type == HeartBeatType.completed) {
|
if (type == HeartBeatType.status || type == HeartBeatType.completed) {
|
||||||
await VideoHttp.heartBeat(
|
await VideoHttp.heartBeat(
|
||||||
|
aid: aid ?? _aid,
|
||||||
bvid: bvid ?? _bvid,
|
bvid: bvid ?? _bvid,
|
||||||
cid: cid ?? _cid,
|
cid: cid ?? _cid,
|
||||||
progress: isComplete ? -1 : progress,
|
progress: isComplete ? -1 : progress,
|
||||||
@@ -1481,6 +1486,7 @@ class PlPlayerController {
|
|||||||
else if (progress - _heartDuration >= 5) {
|
else if (progress - _heartDuration >= 5) {
|
||||||
_heartDuration = progress;
|
_heartDuration = progress;
|
||||||
await VideoHttp.heartBeat(
|
await VideoHttp.heartBeat(
|
||||||
|
aid: aid ?? _aid,
|
||||||
bvid: bvid ?? _bvid,
|
bvid: bvid ?? _bvid,
|
||||||
cid: cid ?? _cid,
|
cid: cid ?? _cid,
|
||||||
progress: progress,
|
progress: progress,
|
||||||
|
|||||||
@@ -463,6 +463,14 @@ class PiliScheme {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
case 'cheese':
|
||||||
|
// bilibili://cheese/season/123456
|
||||||
|
String? seasonId = uriDigitRegExp.firstMatch(path)?.group(1);
|
||||||
|
if (seasonId != null) {
|
||||||
|
PageUtils.viewPugv(seasonId: seasonId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
default:
|
default:
|
||||||
if (!selfHandle) {
|
if (!selfHandle) {
|
||||||
// if (kDebugMode) debugPrint('$uri');
|
// if (kDebugMode) debugPrint('$uri');
|
||||||
@@ -818,6 +826,7 @@ class PiliScheme {
|
|||||||
launchURL();
|
launchURL();
|
||||||
return false;
|
return false;
|
||||||
case 'cheese':
|
case 'cheese':
|
||||||
|
// https://www.bilibili.com/cheese/play/ss123456
|
||||||
bool hasMatch = PageUtils.viewPgcFromUri(path, isPgc: false);
|
bool hasMatch = PageUtils.viewPgcFromUri(path, isPgc: false);
|
||||||
if (hasMatch) {
|
if (hasMatch) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import 'package:PiliPlus/models/common/video/video_type.dart';
|
|||||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/episode.dart';
|
import 'package:PiliPlus/models_new/pgc/pgc_info_model/episode.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/result.dart';
|
import 'package:PiliPlus/models_new/pgc/pgc_info_model/result.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/section.dart';
|
|
||||||
import 'package:PiliPlus/pages/common/common_intro_controller.dart';
|
import 'package:PiliPlus/pages/common/common_intro_controller.dart';
|
||||||
import 'package:PiliPlus/pages/contact/view.dart';
|
import 'package:PiliPlus/pages/contact/view.dart';
|
||||||
import 'package:PiliPlus/pages/fav_panel/view.dart';
|
import 'package:PiliPlus/pages/fav_panel/view.dart';
|
||||||
@@ -699,6 +698,7 @@ class PageUtils {
|
|||||||
String uri, {
|
String uri, {
|
||||||
bool isPgc = true,
|
bool isPgc = true,
|
||||||
String? progress,
|
String? progress,
|
||||||
|
int? aid,
|
||||||
}) {
|
}) {
|
||||||
RegExpMatch? match = _pgcRegex.firstMatch(uri);
|
RegExpMatch? match = _pgcRegex.firstMatch(uri);
|
||||||
if (match != null) {
|
if (match != null) {
|
||||||
@@ -714,6 +714,7 @@ class PageUtils {
|
|||||||
viewPugv(
|
viewPugv(
|
||||||
seasonId: isSeason ? id : null,
|
seasonId: isSeason ? id : null,
|
||||||
epId: isSeason ? null : id,
|
epId: isSeason ? null : id,
|
||||||
|
aid: aid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -721,6 +722,22 @@ class PageUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EpisodeItem findEpisode(
|
||||||
|
List<EpisodeItem> episodes, {
|
||||||
|
dynamic epId,
|
||||||
|
bool isPgc = true,
|
||||||
|
}) {
|
||||||
|
// epId episode -> progress episode -> first episode
|
||||||
|
EpisodeItem? episode;
|
||||||
|
if (epId != null) {
|
||||||
|
epId = epId.toString();
|
||||||
|
episode = episodes.firstWhereOrNull(
|
||||||
|
(item) => (isPgc ? item.epId : item.id).toString() == epId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return episode ?? episodes.first;
|
||||||
|
}
|
||||||
|
|
||||||
static Future<void> viewPgc({
|
static Future<void> viewPgc({
|
||||||
dynamic seasonId,
|
dynamic seasonId,
|
||||||
dynamic epId,
|
dynamic epId,
|
||||||
@@ -732,30 +749,42 @@ class PageUtils {
|
|||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
if (result.isSuccess) {
|
if (result.isSuccess) {
|
||||||
PgcInfoModel data = result.data;
|
PgcInfoModel data = result.data;
|
||||||
|
final episodes = data.episodes;
|
||||||
|
|
||||||
// epId episode -> progress episode -> first episode
|
if (episodes != null && episodes.isNotEmpty) {
|
||||||
EpisodeItem? episode;
|
final EpisodeItem episode = findEpisode(
|
||||||
|
episodes,
|
||||||
if (epId != null) {
|
epId: epId ?? data.userStatus?.progress?.lastEpId,
|
||||||
if (data.episodes?.isNotEmpty == true) {
|
|
||||||
episode = data.episodes!.firstWhereOrNull(
|
|
||||||
(item) {
|
|
||||||
return item.epId.toString() == epId.toString();
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
if (episode == null && data.section?.isNotEmpty == true) {
|
|
||||||
for (Section item in data.section!) {
|
|
||||||
if (item.episodes?.isNotEmpty == true) {
|
|
||||||
for (EpisodeItem item in item.episodes!) {
|
|
||||||
if (item.epId.toString() == epId.toString()) {
|
|
||||||
// view as normal video
|
|
||||||
toVideoPage(
|
toVideoPage(
|
||||||
'bvid=${item.bvid}&cid=${item.cid}&seasonId=${data.seasonId}&epId=${item.epId}',
|
'bvid=${episode.bvid}&cid=${episode.cid}&seasonId=${data.seasonId}&epId=${episode.epId}&type=${data.type}',
|
||||||
|
arguments: {
|
||||||
|
'pic': episode.cover,
|
||||||
|
'heroTag': Utils.makeHeroTag(episode.cid),
|
||||||
|
'videoType': VideoType.pgc,
|
||||||
|
'pgcItem': data,
|
||||||
|
if (progress != null) 'progress': int.tryParse(progress),
|
||||||
|
},
|
||||||
|
preventDuplicates: false,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// find section
|
||||||
|
if (epId != null) {
|
||||||
|
final sections = data.section;
|
||||||
|
if (sections != null && sections.isNotEmpty) {
|
||||||
|
epId = epId.toString();
|
||||||
|
for (var section in sections) {
|
||||||
|
final episodes = section.episodes;
|
||||||
|
if (episodes != null && episodes.isNotEmpty) {
|
||||||
|
for (var episode in episodes) {
|
||||||
|
if (episode.epId.toString() == epId) {
|
||||||
|
// view as ugc
|
||||||
|
toVideoPage(
|
||||||
|
'bvid=${episode.bvid}&cid=${episode.cid}&seasonId=${data.seasonId}&epId=${episode.epId}',
|
||||||
arguments: {
|
arguments: {
|
||||||
'pgcApi': true,
|
'pgcApi': true,
|
||||||
'pic': item.cover,
|
'pic': episode.cover,
|
||||||
'heroTag': Utils.makeHeroTag(item.cid),
|
'heroTag': Utils.makeHeroTag(episode.cid),
|
||||||
'videoType': VideoType.ugc,
|
'videoType': VideoType.ugc,
|
||||||
if (progress != null)
|
if (progress != null)
|
||||||
'progress': int.tryParse(progress),
|
'progress': int.tryParse(progress),
|
||||||
@@ -769,29 +798,8 @@ class PageUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.episodes.isNullOrEmpty) {
|
|
||||||
SmartDialog.showToast('资源加载失败');
|
SmartDialog.showToast('资源加载失败');
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
episode ??= data.userStatus?.progress?.lastEpId != null
|
|
||||||
? data.episodes!.firstWhereOrNull(
|
|
||||||
(item) => item.epId == data.userStatus?.progress?.lastEpId,
|
|
||||||
) ??
|
|
||||||
data.episodes!.first
|
|
||||||
: data.episodes!.first;
|
|
||||||
toVideoPage(
|
|
||||||
'bvid=${episode.bvid}&cid=${episode.cid}&seasonId=${data.seasonId}&epId=${episode.epId}&type=${data.type}',
|
|
||||||
arguments: {
|
|
||||||
'pic': episode.cover,
|
|
||||||
'heroTag': Utils.makeHeroTag(episode.cid),
|
|
||||||
'videoType': VideoType.pgc,
|
|
||||||
'pgcItem': data,
|
|
||||||
if (progress != null) 'progress': int.tryParse(progress),
|
|
||||||
},
|
|
||||||
preventDuplicates: false,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
result.toast();
|
result.toast();
|
||||||
}
|
}
|
||||||
@@ -802,27 +810,40 @@ class PageUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> viewPugv({dynamic seasonId, dynamic epId}) async {
|
static Future<void> viewPugv({
|
||||||
|
dynamic seasonId,
|
||||||
|
dynamic epId,
|
||||||
|
int? aid,
|
||||||
|
}) async {
|
||||||
try {
|
try {
|
||||||
SmartDialog.showLoading(msg: '资源获取中');
|
SmartDialog.showLoading(msg: '资源获取中');
|
||||||
var res = await SearchHttp.pugvInfo(seasonId: seasonId, epId: epId);
|
var res = await SearchHttp.pugvInfo(seasonId: seasonId, epId: epId);
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
if (res.isSuccess) {
|
if (res.isSuccess) {
|
||||||
PgcInfoModel data = res.data;
|
PgcInfoModel data = res.data;
|
||||||
if (data.episodes?.isNotEmpty == true) {
|
final episodes = data.episodes;
|
||||||
final item = data.episodes!.first;
|
if (episodes != null && episodes.isNotEmpty) {
|
||||||
|
EpisodeItem? episode;
|
||||||
|
if (aid != null) {
|
||||||
|
episode = episodes.firstWhereOrNull((e) => e.aid == aid);
|
||||||
|
}
|
||||||
|
episode ??= findEpisode(
|
||||||
|
episodes,
|
||||||
|
epId: epId ?? data.userStatus?.progress?.lastEpId,
|
||||||
|
isPgc: false,
|
||||||
|
);
|
||||||
toVideoPage(
|
toVideoPage(
|
||||||
'bvid=${IdUtils.av2bv(item.aid!)}&cid=${item.cid}&seasonId=${data.seasonId}&epId=${item.id}',
|
'bvid=${IdUtils.av2bv(episode.aid!)}&cid=${episode.cid}&seasonId=${data.seasonId}&epId=${episode.id}',
|
||||||
arguments: {
|
arguments: {
|
||||||
'pic': item.cover,
|
'pic': episode.cover,
|
||||||
'heroTag': Utils.makeHeroTag(item.cid),
|
'heroTag': Utils.makeHeroTag(episode.cid),
|
||||||
'videoType': VideoType.pugv,
|
'videoType': VideoType.pugv,
|
||||||
'pgcItem': data,
|
'pgcItem': data,
|
||||||
},
|
},
|
||||||
preventDuplicates: false,
|
preventDuplicates: false,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
SmartDialog.showToast('NULL');
|
SmartDialog.showToast('资源加载失败');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.toast();
|
res.toast();
|
||||||
|
|||||||
Reference in New Issue
Block a user