Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat external player #31

Merged
merged 5 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@
"theme-dark": "Dark",
"nsfw": "NSFW",
"nsfw-subtitle": "Show NSFW content",
"external-player": "Preferred video player",
"external-player-subtitle": "Currently, the preferred player is {player}",
"external-player-builtin": "Built-in",
"language-subtitle": "Change the language of the software",
"extension-log": "Extension Log Window",
"extension-log-subtitle": "Used for debugging extensions",
Expand All @@ -100,6 +103,8 @@
"license-subtitle": "License"
},

"external-player-launching": "Launching {player}",

"detail": {
"favorite": "Favorite",
"favorited": "Favorited",
Expand Down
5 changes: 5 additions & 0 deletions assets/i18n/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@
"theme-dark": "深色",
"nsfw": "NSFW",
"nsfw-subtitle": "显示 NSFW 内容",
"external-player": "优先使用的视频播放器",
"external-player-subtitle": "当前优先使用的是 {player}",
"external-player-builtin": "内置播放器",
"language-subtitle": "选择软件的语言",
"extension-log": "扩展日志窗口",
"extension-log-subtitle": "用于调试扩展",
Expand All @@ -89,6 +92,8 @@
"license-subtitle": "许可证"
},

"external-player-launching": "正在启动 {player}",

"detail": {
"favorite": "收藏",
"favorited": "已收藏",
Expand Down
46 changes: 45 additions & 1 deletion lib/pages/detail/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import 'package:miru_app/router/router.dart';
import 'package:miru_app/utils/database.dart';
import 'package:miru_app/utils/extension.dart';
import 'package:miru_app/utils/extension_runtime.dart';
import 'package:miru_app/utils/external_player.dart';
import 'package:miru_app/utils/i18n.dart';
import 'package:miru_app/utils/miru_directory.dart';
import 'package:miru_app/utils/miru_storage.dart';
Expand Down Expand Up @@ -307,7 +308,7 @@ class DetailPageController extends GetxController {
List<ExtensionEpisode> urls,
int index,
int selectEpGroup,
) {
) async {
if (runtime.value == null) {
showPlatformSnackbar(
context: cuurentContext,
Expand All @@ -323,6 +324,49 @@ class DetailPageController extends GetxController {
return;
}

if (type == ExtensionType.bangumi) {
final player = MiruStorage.getSetting(SettingKey.videoPlayer);

if (player != 'built-in') {
showPlatformSnackbar(
context: cuurentContext,
content: FlutterI18n.translate(
cuurentContext,
'external-player-launching',
translationParams: {
'player': player,
},
),
);
late ExtensionBangumiWatch watchData;
try {
watchData = await runtime.value!.watch(urls[index].url)
as ExtensionBangumiWatch;
} catch (e) {
showPlatformSnackbar(
context: cuurentContext,
content: e.toString().split('\n')[0],
severity: fluent.InfoBarSeverity.error,
);
return;
}
try {
if (GetPlatform.isMobile) {
await launchMobileExternalPlayer(watchData.url, player);
return;
}
await launchDesktopExternalPlayer(watchData.url, player);
return;
} catch (e) {
showPlatformSnackbar(
context: cuurentContext,
content: e.toString().split('\n')[0],
severity: fluent.InfoBarSeverity.error,
);
}
}
}

Navigator.of(context, rootNavigator: true).push(
PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 600),
Expand Down
1 change: 0 additions & 1 deletion lib/pages/detail/view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'package:get/get.dart';
import 'package:miru_app/api/tmdb.dart';
import 'package:miru_app/models/extension.dart';
import 'package:miru_app/pages/detail/controller.dart';
import 'package:miru_app/pages/detail/pages/tmdb_binding.dart';
import 'package:miru_app/pages/detail/pages/webview.dart';
import 'package:miru_app/pages/detail/widgets/detail_appbar_flexible_space.dart';
import 'package:miru_app/pages/detail/widgets/detail_appbar_title.dart';
Expand Down
35 changes: 35 additions & 0 deletions lib/pages/settings/view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,41 @@ class _SettingsPageState extends State<SettingsPage> {
},
),
const SizedBox(height: 8),
SettingsRadiosTile(
icon: const PlatformWidget(
androidWidget: Icon(Icons.play_arrow),
desktopWidget: Icon(fluent.FluentIcons.play_resume, size: 24),
),
title: 'settings.external-player'.i18n,
itemNameValue: () {
if (Platform.isAndroid) {
return {
"settings.external-player-builtin".i18n: "built-in",
"VLC": "vlc",
"Other": "other",
};
}
return {
"settings.external-player-builtin".i18n: "built-in",
"VLC": "vlc",
"PotPlayer": "potplayer",
};
}(),
buildSubtitle: () => FlutterI18n.translate(
context,
'settings.external-player-subtitle',
translationParams: {
'player': MiruStorage.getSetting(SettingKey.videoPlayer),
},
),
applyValue: (value) {
MiruStorage.setSetting(SettingKey.videoPlayer, value);
},
buildGroupValue: () {
return MiruStorage.getSetting(SettingKey.videoPlayer);
},
),
const SizedBox(height: 8),
if (!Platform.isAndroid)
Obx(
() {
Expand Down
38 changes: 38 additions & 0 deletions lib/utils/external_player.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'dart:io';

import 'package:android_intent_plus/android_intent.dart';
import 'package:url_launcher/url_launcher_string.dart';

Future<void> launchMobileExternalPlayer(String playUrl, String player) async {
switch (player) {
case "vlc":
await _launchExternalPlayer("vlc://$playUrl");
break;
case "other":
await AndroidIntent(
action: 'action_view',
data: playUrl,
type: 'video/*',
).launch();
break;
}
}

// desktop
Future<void> launchDesktopExternalPlayer(String playUrl, String player) async {
switch (player) {
case "vlc":
const vlc = 'C:\\Program Files\\VideoLAN\\VLC\\vlc.exe';
await Process.run(vlc, [playUrl]);
break;
case "potplayer":
await _launchExternalPlayer("potplayer://$playUrl");
break;
}
}

_launchExternalPlayer(String url) async {
if (!await launchUrlString(url, mode: LaunchMode.externalApplication)) {
throw Exception("Failed to launch $url");
}
}
2 changes: 2 additions & 0 deletions lib/utils/miru_storage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class MiruStorage {
await _initSetting(SettingKey.novelFontSize, 18.0);
await _initSetting(SettingKey.theme, 'system');
await _initSetting(SettingKey.enableNSFW, false);
await _initSetting(SettingKey.videoPlayer, 'built-in');
}

static _initSetting(String key, dynamic value) async {
Expand All @@ -136,5 +137,6 @@ class SettingKey {
static String language = 'Language';
static String novelFontSize = 'NovelFontSize';
static String enableNSFW = 'EnableNSFW';
static String videoPlayer = 'VideoPlayer';
static String databaseVersion = 'DatabaseVersion';
}
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.13.0"
android_intent_plus:
dependency: "direct main"
description:
name: android_intent_plus
sha256: f72ae20bb37108694f442e7ae6acbd28b453ca62ce86842f6787b784355abfe6
url: "https://pub.dev"
source: hosted
version: "4.0.2"
archive:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ dependencies:
http_parser: ^4.0.2
html: ^0.15.4
xpath_selector_html_parser: ^3.0.1
android_intent_plus: ^4.0.2

dev_dependencies:
flutter_test:
Expand Down