Skip to content

Commit

Permalink
replace media_kit with fvp
Browse files Browse the repository at this point in the history
  • Loading branch information
Predidit committed Jul 14, 2024
1 parent 33ac64b commit 62ab40b
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 240 deletions.
6 changes: 4 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 4,7 @@ import 'package:flutter/material.dart';
import 'package:kazumi/app_module.dart';
import 'package:kazumi/app_widget.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:media_kit/media_kit.dart';
import 'package:fvp/fvp.dart' as fvp;
import 'package:path_provider/path_provider.dart';
import 'package:kazumi/utils/storage.dart';
import 'package:hive_flutter/hive_flutter.dart';
Expand Down Expand Up @@ -38,7 38,9 @@ void main() async {
statusBarColor: Colors.transparent,
));
}
MediaKit.ensureInitialized();
fvp.registerWith(options: {
'platforms': ['windows', 'linux']
});
await Hive.initFlutter('${(await getApplicationSupportDirectory()).path}/hive');
await GStorage.init();
Request();
Expand Down
94 changes: 28 additions & 66 deletions lib/pages/player/player_controller.dart
Original file line number Diff line number Diff line change
@@ -1,6 1,4 @@
import 'dart:io';
import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
import 'package:video_player/video_player.dart';
import 'package:kazumi/modules/danmaku/danmaku_module.dart';
import 'package:flutter/material.dart' show debugPrint;
import 'package:mobx/mobx.dart';
Expand All @@ -23,8 21,7 @@ abstract class _PlayerController with Store {
String videoUrl = '';
// 弹幕ID
int bangumiID = 0;
late Player mediaPlayer;
late VideoController videoController;
late VideoPlayerController mediaPlayer;
late DanmakuController danmakuController;
final VideoPageController videoPageController =
Modular.get<VideoPageController>();
Expand Down Expand Up @@ -88,18 85,13 @@ abstract class _PlayerController with Store {
}
debugPrint('VideoItem开始初始化');
mediaPlayer = await createVideoController();
bool aotoPlay = setting.get(SettingBoxKey.autoPlay, defaultValue: true);
playerSpeed = 1.0;
if (offset != 0) {
var sub = mediaPlayer.stream.buffer.listen(null);
sub.onData((event) async {
if (event.inSeconds > 0) {
// This is a workaround for unable to await for `mediaPlayer.stream.buffer.first`
// It seems that when the `buffer.first` is fired, the media is not fully loaded
// and the player will not seek properlly.
await sub.cancel();
await mediaPlayer.seek(Duration(seconds: offset));
}
});
await mediaPlayer.seekTo(Duration(seconds: offset));
}
if (aotoPlay) {
await mediaPlayer.play();
}
debugPrint('VideoURL初始化完成');
// 加载弹幕
Expand All @@ -108,76 100,46 @@ abstract class _PlayerController with Store {
loading = false;
}

Future<Player> createVideoController() async {
mediaPlayer = Player(
configuration: const PlayerConfiguration(
// 默认缓存 5M 大小
bufferSize: 5 * 1024 * 1024,
),
);

var pp = mediaPlayer.platform as NativePlayer;
// 解除倍速限制
await pp.setProperty("af", "scaletempo2=max-speed=8");
// 音量不一致
if (Platform.isAndroid) {
await pp.setProperty("volume-max", "100");
await pp.setProperty("ao", "audiotrack,opensles");
}

await mediaPlayer.setAudioTrack(
AudioTrack.auto(),
);

hAenable = setting.get(SettingBoxKey.hAenable, defaultValue: true);

videoController = VideoController(
mediaPlayer,
configuration: VideoControllerConfiguration(
enableHardwareAcceleration: hAenable,
androidAttachSurfaceAfterVideoParameters: false,
),
);
mediaPlayer.setPlaylistMode(PlaylistMode.none);
debugPrint('videoController 配置成功 $videoUrl');

Future<VideoPlayerController> createVideoController() async {
String userAgent = '';
if (videoPageController.currentPlugin.userAgent == '') {
mediaPlayer.open(
Media(videoUrl),
play: true,
);
userAgent =
'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';
} else {
debugPrint('media_kit UA: ${videoPageController.currentPlugin.userAgent}');
var httpHeaders = {
'user-agent': videoPageController.currentPlugin.userAgent,
};
mediaPlayer.open(
Media(videoUrl, httpHeaders: httpHeaders),
play: true,
);
debugPrint(
'media_kit UA: ${videoPageController.currentPlugin.userAgent}');
userAgent = videoPageController.currentPlugin.userAgent;
}
var httpHeaders = {
'user-agent': userAgent,
};
mediaPlayer = VideoPlayerController.networkUrl(Uri.parse(videoUrl),
httpHeaders: httpHeaders);
await mediaPlayer.initialize();
debugPrint('videoController 配置成功 $videoUrl');
return mediaPlayer;
}

Future setPlaybackSpeed(double playerSpeed) async {
this.playerSpeed = playerSpeed;
try {
mediaPlayer.setRate(playerSpeed);
mediaPlayer.setPlaybackSpeed(playerSpeed);
} catch (e) {
debugPrint(e.toString());
}
}

Future playOrPause() async {
mediaPlayer.state.playing
? danmakuController.pause()
: danmakuController.resume();
await mediaPlayer.playOrPause();
if (mediaPlayer.value.isPlaying) {
await pause();
} else {
await play();
}
}

Future seek(Duration duration) async {
danmakuController.clear();
await mediaPlayer.seek(duration);
await mediaPlayer.seekTo(duration);
}

Future pause() async {
Expand Down
87 changes: 39 additions & 48 deletions lib/pages/player/player_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 9,7 @@ import 'package:flutter/gestures.dart';
import 'package:kazumi/pages/player/player_controller.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:media_kit_video/media_kit_video.dart';
import 'package:video_player/video_player.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:kazumi/pages/video/video_controller.dart';
import 'package:window_manager/window_manager.dart';
Expand All @@ -34,7 34,8 @@ class PlayerItem extends StatefulWidget {
State<PlayerItem> createState() => _PlayerItemState();
}

class _PlayerItemState extends State<PlayerItem> with WindowListener {
class _PlayerItemState extends State<PlayerItem>
with WindowListener, WidgetsBindingObserver {
Box setting = GStorage.setting;
final PlayerController playerController = Modular.get<PlayerController>();
final VideoPageController videoPageController =
Expand Down Expand Up @@ -67,6 68,14 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {
Timer? playerTimer;
Timer? mouseScrollerTimer;

/// 处理 Android/iOS 应用后台或熄屏
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
playerController.pause();
}
}

void _handleTap() {
playerController.showPositioned = true;
if (hideTimer != null) {
Expand All @@ -93,17 102,21 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {

getPlayerTimer() {
return Timer.periodic(const Duration(seconds: 1), (timer) {
playerController.playing = playerController.mediaPlayer.state.playing;
playerController.playing = playerController.mediaPlayer.value.isPlaying;
playerController.isBuffering =
playerController.mediaPlayer.state.buffering;
playerController.mediaPlayer.value.isBuffering;
playerController.currentPosition =
playerController.mediaPlayer.state.position;
playerController.buffer = playerController.mediaPlayer.state.buffer;
playerController.duration = playerController.mediaPlayer.state.duration;
playerController.completed = playerController.mediaPlayer.state.completed;
playerController.mediaPlayer.value.position;
playerController.buffer =
playerController.mediaPlayer.value.buffered.isEmpty
? Duration.zero
: playerController.mediaPlayer.value.buffered[0].end;
playerController.duration = playerController.mediaPlayer.value.duration;
playerController.completed =
playerController.mediaPlayer.value.isCompleted;
// 弹幕相关
if (playerController.currentPosition.inMicroseconds != 0 &&
playerController.mediaPlayer.state.playing == true &&
playerController.mediaPlayer.value.isPlaying == true &&
playerController.danmakuOn == true) {
// debugPrint('当前播放到 ${videoController.currentPosition.inSeconds}');
playerController.danDanmakus[playerController.currentPosition.inSeconds]
Expand All @@ -121,8 134,8 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {
playerController.currentPosition.inSeconds]!
.length),
() => mounted &&
playerController.mediaPlayer.state.playing &&
!playerController.mediaPlayer.state.buffering
playerController.mediaPlayer.value.isPlaying &&
!playerController.mediaPlayer.value.isBuffering
? danmakuController.addDanmaku(DanmakuContentItem(
danmaku.message,
color: danmaku.color,
Expand All @@ -135,13 148,13 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {
});
}
// 历史记录相关
if (playerController.mediaPlayer.state.playing) {
if (playerController.mediaPlayer.value.isPlaying) {
historyController.updateHistory(
videoPageController.currentEspisode,
videoPageController.currentRoad,
videoPageController.currentPlugin.name,
infoController.bangumiItem,
playerController.mediaPlayer.state.position,
playerController.mediaPlayer.value.position,
videoPageController.src);
}
// 自动播放下一集
Expand Down Expand Up @@ -367,6 380,7 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
if (Utils.isCompact()) {
navigationBarState =
Provider.of<NavigationBarState>(context, listen: false);
Expand All @@ -393,7 407,7 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {

@override
void dispose() {
//player.dispose();
WidgetsBinding.instance.removeObserver(this);
if (playerTimer != null) {
playerTimer!.cancel();
}
Expand Down Expand Up @@ -534,7 548,7 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {
child:
Stack(alignment: Alignment.center, children: [
Center(child: playerSurface),
playerController.isBuffering
(playerController.isBuffering || playerController.loading)
? const Positioned.fill(
child: Center(
child: CircularProgressIndicator(),
Expand Down Expand Up @@ -683,11 697,11 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {
.compareTo(
playerController
.mediaPlayer
.state
.value
.position) >
0
? '快进 ${playerController.currentPosition.inSeconds - playerController.mediaPlayer.state.position.inSeconds} 秒'
: '快退 ${playerController.mediaPlayer.state.position.inSeconds - playerController.currentPosition.inSeconds} 秒',
? '快进 ${playerController.currentPosition.inSeconds - playerController.mediaPlayer.value.position.inSeconds} 秒'
: '快退 ${playerController.mediaPlayer.value.position.inSeconds - playerController.currentPosition.inSeconds} 秒',
style: const TextStyle(
color: Colors.white,
),
Expand Down Expand Up @@ -797,7 811,7 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {
// 自定义顶部组件
(playerController.showPositioned ||
!playerController
.mediaPlayer.state.playing)
.mediaPlayer.value.isPlaying)
? Positioned(
top: 0,
left: 0,
Expand Down Expand Up @@ -871,7 885,7 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {
// 自定义播放器底部组件
(playerController.showPositioned ||
!playerController
.mediaPlayer.state.playing)
.mediaPlayer.value.isPlaying)
? Positioned(
bottom: 0,
left: 0,
Expand Down Expand Up @@ -1036,33 1050,10 @@ class _PlayerItemState extends State<PlayerItem> with WindowListener {
}

Widget get playerSurface {
return Video(
controller: playerController.videoController,
controls: NoVideoControls,
subtitleViewConfiguration: SubtitleViewConfiguration(
style: TextStyle(
color: Colors.pink, // 深粉色字体
fontSize: 48.0, // 较大的字号
background: Paint()..color = Colors.transparent, // 背景透明
decoration: TextDecoration.none, // 无下划线
fontWeight: FontWeight.bold, // 字体加粗
shadows: const [
// 显眼的包边
Shadow(
offset: Offset(1.0, 1.0),
blurRadius: 3.0,
color: Color.fromARGB(255, 255, 255, 255),
),
Shadow(
offset: Offset(-1.0, -1.0),
blurRadius: 3.0,
color: Color.fromARGB(125, 255, 255, 255),
),
],
),
textAlign: TextAlign.center,
padding: const EdgeInsets.all(24.0),
),
);
return AspectRatio(
aspectRatio: playerController.mediaPlayer.value.aspectRatio,
child: VideoPlayer(
playerController.mediaPlayer,
));
}
}
12 changes: 4 additions & 8 deletions linux/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 7,7 @@
#include "generated_plugin_registrant.h"

#include <flutter_volume_controller/flutter_volume_controller_plugin.h>
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
#include <media_kit_video/media_kit_video_plugin.h>
#include <fvp/fvp_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
#include <window_manager/window_manager_plugin.h>
Expand All @@ -17,12 16,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_volume_controller_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterVolumeControllerPlugin");
flutter_volume_controller_plugin_register_with_registrar(flutter_volume_controller_registrar);
g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin");
media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar);
g_autoptr(FlPluginRegistrar) media_kit_video_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin");
media_kit_video_plugin_register_with_registrar(media_kit_video_registrar);
g_autoptr(FlPluginRegistrar) fvp_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FvpPlugin");
fvp_plugin_register_with_registrar(fvp_registrar);
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
Expand Down
4 changes: 1 addition & 3 deletions linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 4,13 @@

list(APPEND FLUTTER_PLUGIN_LIST
flutter_volume_controller
media_kit_libs_linux
media_kit_video
fvp
screen_retriever
url_launcher_linux
window_manager
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
media_kit_native_event_loop
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Loading

0 comments on commit 62ab40b

Please sign in to comment.