mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-08-05 19:59:51 +00:00
fix: queue shows 0:00 duration for sourced tracks
YouTubeEngine passed track duration in seconds while SpotubeAudioSourceMatchObject.fromJson interprets `duration` as microseconds, so durations collapsed to ~0 and the queue displayed 0:00. - lib/services/metadata/metadata.dart: send duration in microseconds (search() and getVideo() callbacks) - lib/components/track_tile/track_tile.dart, lib/modules/player/player_queue.dart: add resolveMissingDuration so the queue actively resolves the sourced track's real duration when the track's own metadata duration is effectively zero Fixes #3021
This commit is contained in:
parent
69a310c78f
commit
3558ad3b12
@ -21,6 +21,7 @@ import 'package:spotube/models/metadata/metadata.dart';
|
|||||||
import 'package:spotube/provider/audio_player/querying_track_info.dart';
|
import 'package:spotube/provider/audio_player/querying_track_info.dart';
|
||||||
import 'package:spotube/provider/audio_player/state.dart';
|
import 'package:spotube/provider/audio_player/state.dart';
|
||||||
import 'package:spotube/provider/blacklist_provider.dart';
|
import 'package:spotube/provider/blacklist_provider.dart';
|
||||||
|
import 'package:spotube/provider/server/sourced_track_provider.dart';
|
||||||
import 'package:spotube/utils/platform.dart';
|
import 'package:spotube/utils/platform.dart';
|
||||||
|
|
||||||
final isBlacklistedProvider =
|
final isBlacklistedProvider =
|
||||||
@ -46,6 +47,7 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
final bool userPlaylist;
|
final bool userPlaylist;
|
||||||
final String? playlistId;
|
final String? playlistId;
|
||||||
final AudioPlayerState playlist;
|
final AudioPlayerState playlist;
|
||||||
|
final bool resolveMissingDuration;
|
||||||
|
|
||||||
final List<Widget>? leadingActions;
|
final List<Widget>? leadingActions;
|
||||||
|
|
||||||
@ -62,6 +64,7 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
this.userPlaylist = false,
|
this.userPlaylist = false,
|
||||||
this.playlistId,
|
this.playlistId,
|
||||||
this.leadingActions,
|
this.leadingActions,
|
||||||
|
this.resolveMissingDuration = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -88,6 +91,16 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
// toggling a dedicated `selectionMode` flag (e.g. playlists), so we must
|
// toggling a dedicated `selectionMode` flag (e.g. playlists), so we must
|
||||||
// disable inner navigation in both cases.
|
// disable inner navigation in both cases.
|
||||||
final effectiveSelection = selectionMode || onChanged != null;
|
final effectiveSelection = selectionMode || onChanged != null;
|
||||||
|
final sourcedTrack = resolveMissingDuration &&
|
||||||
|
track is SpotubeFullTrackObject &&
|
||||||
|
track.durationMs < Duration.millisecondsPerSecond
|
||||||
|
? ref.watch(sourcedTrackProvider(track as SpotubeFullTrackObject))
|
||||||
|
: null;
|
||||||
|
final duration = sourcedTrack?.maybeWhen(
|
||||||
|
data: (track) => track.info.duration,
|
||||||
|
orElse: () => Duration(milliseconds: this.track.durationMs),
|
||||||
|
) ??
|
||||||
|
Duration(milliseconds: track.durationMs);
|
||||||
|
|
||||||
return LayoutBuilder(builder: (context, constrains) {
|
return LayoutBuilder(builder: (context, constrains) {
|
||||||
return Listener(
|
return Listener(
|
||||||
@ -322,8 +335,7 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Text(
|
Text(
|
||||||
Duration(milliseconds: track.durationMs)
|
duration.toHumanReadableString(padZero: false),
|
||||||
.toHumanReadableString(padZero: false),
|
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -308,6 +308,7 @@ class PlayerQueue extends HookConsumerWidget {
|
|||||||
playlist: playlist,
|
playlist: playlist,
|
||||||
index: i,
|
index: i,
|
||||||
track: track,
|
track: track,
|
||||||
|
resolveMissingDuration: true,
|
||||||
selectionMode: selectionMode.value,
|
selectionMode: selectionMode.value,
|
||||||
selected:
|
selected:
|
||||||
selectedTrackIds.value.contains(track.id),
|
selectedTrackIds.value.contains(track.id),
|
||||||
|
|||||||
@ -90,7 +90,7 @@ class MetadataPlugin {
|
|||||||
'id': video.id.value,
|
'id': video.id.value,
|
||||||
'title': video.title,
|
'title': video.title,
|
||||||
'author': video.author,
|
'author': video.author,
|
||||||
'duration': video.duration?.inSeconds,
|
'duration': video.duration?.inMicroseconds,
|
||||||
'description': video.description,
|
'description': video.description,
|
||||||
'uploadDate': video.uploadDate?.toIso8601String(),
|
'uploadDate': video.uploadDate?.toIso8601String(),
|
||||||
'viewCount': video.engagement.viewCount,
|
'viewCount': video.engagement.viewCount,
|
||||||
@ -105,7 +105,7 @@ class MetadataPlugin {
|
|||||||
'id': video.id.value,
|
'id': video.id.value,
|
||||||
'title': video.title,
|
'title': video.title,
|
||||||
'author': video.author,
|
'author': video.author,
|
||||||
'duration': video.duration?.inSeconds,
|
'duration': video.duration?.inMicroseconds,
|
||||||
'description': video.description,
|
'description': video.description,
|
||||||
'uploadDate': video.uploadDate?.toIso8601String(),
|
'uploadDate': video.uploadDate?.toIso8601String(),
|
||||||
'viewCount': video.engagement.viewCount,
|
'viewCount': video.engagement.viewCount,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user