Skip to content

Commit

Permalink
fix: download button popup unlimited loading
Browse files Browse the repository at this point in the history
  • Loading branch information
prateekmedia committed Mar 30, 2024
1 parent 8d6efcf commit 129e0a2
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 51 deletions.
28 changes: 17 additions & 11 deletions lib/foundation/show_download_popover.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Future<dynamic> showDownloadPopup(
);
}

class _DownloadWrapper extends ConsumerWidget {
class _DownloadWrapper extends ConsumerStatefulWidget {
const _DownloadWrapper({
required this.video,
required this.videoUrl,
Expand All @@ -55,20 +55,26 @@ class _DownloadWrapper extends ConsumerWidget {
final bool isClickable;

@override
Widget build(BuildContext context, WidgetRef ref) {
final videoData = videoUrl != null || video?.audioStreams == null
? ref.read(
videoInfoProvider(
videoUrl != null ? VideoId(videoUrl!) : video!.id,
),
)
: null;
ConsumerState<_DownloadWrapper> createState() => _DownloadWrapperState();
}

final loadedVideo = video?.videoStreams != null ? video! : videoData!.value;
class _DownloadWrapperState extends ConsumerState<_DownloadWrapper> {
late final provider = videoInfoProvider(
widget.videoUrl != null ? VideoId(widget.videoUrl!) : widget.video!.id,
);
@override
Widget build(BuildContext context) {
final videoData =
widget.videoUrl != null || widget.video?.audioStreams == null
? ref.watch(provider)
: null;

final loadedVideo =
widget.video?.videoStreams != null ? widget.video! : videoData!.value;

return loadedVideo != null
? DownloadsWidget(
isClickable: isClickable,
isClickable: widget.isClickable,
video: loadedVideo,
)
: videoData!.isLoading
Expand Down
10 changes: 5 additions & 5 deletions lib/foundation/view_model/video_info_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ final videoViewModelProvider = Provider<VideoViewModel>((ref) {
return VideoViewModel(pipedService);
});

FutureProvider<VideoData?> videoInfoProvider(VideoId videoId) =>
FutureProvider((ref) async {
final videoViewModel = ref.watch(videoViewModelProvider);
return videoViewModel.getInfo(videoId);
});
final videoInfoProvider = FutureProvider.autoDispose
.family<VideoData?, VideoId>((ref, videoId) async {
final videoViewModel = ref.read(videoViewModelProvider);
return videoViewModel.getInfo(videoId);
});

class VideoViewModel {
VideoViewModel(this.pipedService);
Expand Down
6 changes: 1 addition & 5 deletions lib/ui/screens/home_page/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,7 @@ class MyHomePage extends HookConsumerWidget {
showDownloadPopup(
context,
isClickable: true,
videoUrl: addDownloadController.text
.split('/')
.last
.split('watch?v=')
.last,
videoUrl: addDownloadController.text,
);
}
},
Expand Down
8 changes: 5 additions & 3 deletions lib/ui/widgets/ps_video.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ class PSVideo extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
return FutureBuilder<VideoData?>(
future: videoUrl != null
? ref.watch(pipedServiceProvider).getVideoData(VideoId(videoUrl!))
future: videoUrl != null || videoData?.videoStreams == null
? ref
.read(pipedServiceProvider)
.getVideoData(VideoId(videoUrl ?? videoData!.id.url))
: null,
builder: (context, snapshot) {
final video = snapshot.data ?? videoData;
Expand Down Expand Up @@ -254,7 +256,7 @@ class PSVideo extends ConsumerWidget {

AdwButton getDownloadButton(VideoData? video, BuildContext context) =>
AdwButton.circular(
onPressed: video != null
onPressed: video?.videoStreams != null
? () => showDownloadPopup(
context,
isClickable: true,
Expand Down
81 changes: 54 additions & 27 deletions lib/ui/widgets/video_player_desktop/vid_player_mpv.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: unawaited_futures

import 'dart:io';
import 'dart:math';

Expand Down Expand Up @@ -40,41 +42,53 @@ class _VideoPlayerMpvState extends State<VideoPlayerMpv> {
@override
void initState() {
super.initState();
_selectResolution(widget.resolutions.values.first);
_selectResolution(widget.resolutions.values.first, true);
}

Future<void> _selectResolution(String vid) async {
// The maximum bitrate is needed to select the best audio quality
final maxBitrate = aud.keys.reduce(max);
// The audio URL is needed to load the audio track
final audioUrl = aud[maxBitrate]!;

if (player.platform != null && player.platform is NativePlayer) {
try {
// The audio track is appended to the video track using the NativePlayer method
await (player.platform! as NativePlayer).setProperty(
'audio-files',
Platform.isWindows
? audioUrl.replaceAll(';', r'\;')
: audioUrl.replaceAll(':', r'\:'),
);
} catch (e) {
debugPrint('External Audio error: $e');
Future<void> _selectResolution(String vid, [bool firstTime = false]) async {
Duration? currentPosition;
if (firstTime) {
// The maximum bitrate is needed to select the best audio quality
final maxBitrate = aud.keys.reduce(max);
// The audio URL is needed to load the audio track
final audioUrl = aud[maxBitrate]!;

if (player.platform != null && player.platform is NativePlayer) {
try {
// The audio track is appended to the video track using the NativePlayer method
await (player.platform! as NativePlayer).setProperty(
'audio-files',
Platform.isWindows
? audioUrl.replaceAll(';', r'\;')
: audioUrl.replaceAll(':', r'\:'),
);
} catch (e) {
debugPrint('External Audio error: $e');
}
}
} else {
await player.pause();
currentPosition = player.state.position;
}

// The playlist with both audio and video tracks is opened by the player
// await player.open(Playlist(medias));
// Alternatively, only the video track can be opened by the player
await player.open(Playlist([Media(vid)]));
await player.open(Playlist([Media(vid)]), play: firstTime);

setState(() {
final aspectlist = aspect.entries.toList();
final h = aspectlist[0].key;
final w = aspectlist[0].value;
if (firstTime) {
setState(() {
final aspectlist = aspect.entries.toList();
final h = aspectlist[0].key;
final w = aspectlist[0].value;

aspectvalue = h / w;
});
aspectvalue = h / w;
});
}
if (currentPosition != null) {
await player.seek(currentPosition).then((value) => player.play());
setState(() {});
}
}

@override
Expand All @@ -91,6 +105,7 @@ class _VideoPlayerMpvState extends State<VideoPlayerMpv> {
// Use [Video] widget to display video output.
child: MaterialDesktopVideoControlsTheme(
fullscreen: MaterialDesktopVideoControlsThemeData(
modifyVolumeOnScroll: false,
bottomButtonBar: [
const MaterialDesktopSkipPreviousButton(),
const MaterialDesktopPlayOrPauseButton(),
Expand All @@ -117,6 +132,7 @@ class _VideoPlayerMpvState extends State<VideoPlayerMpv> {
],
),
normal: MaterialDesktopVideoControlsThemeData(
modifyVolumeOnScroll: false,
bottomButtonBar: [
const MaterialDesktopSkipPreviousButton(),
const MaterialDesktopPlayOrPauseButton(),
Expand Down Expand Up @@ -164,8 +180,19 @@ class _VideoPlayerMpvState extends State<VideoPlayerMpv> {
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text(
entry.key,
child: Row(
children: [
Text(
entry.key,
),
if (quality == entry.key) ...[
const SizedBox(width: 8),
const Icon(
Icons.check,
size: 18,
),
],
],
),
),
);
Expand Down

0 comments on commit 129e0a2

Please sign in to comment.