[vlc-devel] [PATCH] macosx: Display internal track titles from cue/m3u files in playqueue

Felix Paul Kühne fkuehne at videolan.org
Sun Jun 1 10:59:32 UTC 2025


Hello Astrom,

We no longer accept contributions as patches. Please create an account on https://code.videolan.org <https://code.videolan.org/> and file a merge request against VLC.

Thanks!

Felix

> On 1. Jun 2025, at 12:17, Astrom <xifengcun at hotmail.com> wrote:
> 
> From: Astrom Cheng <xifengcun at hotmail.com>
> 
> This commit enhances the macOS playqueue UI to properly display track-specific
> titles from cue sheets and m3u playlists instead of showing generic file names.
> 
> Key changes:
> - **VLCPlayQueueTableCellView**: Enhanced title display logic to prioritize
>  `inputItem.title` over generic `item.title` when available, with optional
>  track number prefixing (format: "Track# · Title")
> - **VLCPlayQueueController**: Improved `playQueueUpdatedForIndex` to safely
>  replace items using current playlist state rather than potentially stale
>  callback data, preventing crashes during rapid updates
> - **VLCPlayQueueModel**: Added `replaceItemAtIndex:withItem:` method for
>  atomic item replacement in the queue array
> 
> This allows users to see meaningful track titles like "03 · Song Name" instead
> of just the cue/m3u filename for each track, significantly improving the user
> experience when playing cuesheets or structured playlists.
> 
> Addresses playlist metadata display issues where individual tracks from
> cue sheets and m3u files were showing generic filenames rather than their
> embedded track titles and numbers.
> ---
> .../macosx/playqueue/VLCPlayQueueController.m    | 14 +++++++++++---
> modules/gui/macosx/playqueue/VLCPlayQueueModel.h |  2 +-
> modules/gui/macosx/playqueue/VLCPlayQueueModel.m |  7 ++++++-
> .../macosx/playqueue/VLCPlayQueueTableCellView.m | 16 ++++++++++++++--
> 4 files changed, 32 insertions(+), 7 deletions(-)
> 
> diff --git a/modules/gui/macosx/playqueue/VLCPlayQueueController.m b/modules/gui/macosx/playqueue/VLCPlayQueueController.m
> index 5a96e19922..4c3936132f 100644
> --- a/modules/gui/macosx/playqueue/VLCPlayQueueController.m
> +++ b/modules/gui/macosx/playqueue/VLCPlayQueueController.m
> @@ -337,11 +337,19 @@ - (void)playQueueRemovedItemsAtIndex:(size_t)index count:(size_t)numberOfItems
> 
> - (void)playQueueUpdatedForIndex:(size_t)firstUpdatedIndex items:(vlc_playlist_item_t *const *)items count:(size_t)numberOfItems
> {
> -    VLC_UNUSED(items);
> -    for (size_t i = firstUpdatedIndex; i < firstUpdatedIndex + numberOfItems; i++) {
> -        [_playQueueModel updateItemAtIndex:i];
> +    vlc_playlist_Lock(_p_playlist);
> +    for (size_t i = 0; i < numberOfItems; i++) {
> +        size_t replaceIndex = firstUpdatedIndex + i;
> +        if (replaceIndex < vlc_playlist_Count(_p_playlist)) {
> +            vlc_playlist_item_t *currentItem = vlc_playlist_Get(_p_playlist, replaceIndex);
> +            VLCPlayQueueItem *newItem = [[VLCPlayQueueItem alloc] initWithPlaylistItem:currentItem];
> +            [_playQueueModel replaceItemAtIndex:replaceIndex withItem:newItem];
> +        }
>     }
> +    vlc_playlist_Unlock(_p_playlist);
> +
>     [_playQueueDataSource playQueueUpdated];
> +
> }
> 
> - (void)playQueuePlaybackRepeatUpdated:(enum vlc_playlist_playback_repeat)currentRepeatMode
> diff --git a/modules/gui/macosx/playqueue/VLCPlayQueueModel.h b/modules/gui/macosx/playqueue/VLCPlayQueueModel.h
> index 4e94aa6ecc..1f5da8e3bf 100644
> --- a/modules/gui/macosx/playqueue/VLCPlayQueueModel.h
> +++ b/modules/gui/macosx/playqueue/VLCPlayQueueModel.h
> @@ -40,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
> - (void)moveItemAtIndex:(size_t)index toTarget:(size_t)target;
> - (void)removeItemsInRange:(NSRange)range;
> - (void)updateItemAtIndex:(size_t)index;
> -
> +- (void)replaceItemAtIndex:(size_t)index withItem:(VLCPlayQueueItem *)newItem;
> @end
> 
> NS_ASSUME_NONNULL_END
> diff --git a/modules/gui/macosx/playqueue/VLCPlayQueueModel.m b/modules/gui/macosx/playqueue/VLCPlayQueueModel.m
> index b596f87511..5430e5c226 100644
> --- a/modules/gui/macosx/playqueue/VLCPlayQueueModel.m
> +++ b/modules/gui/macosx/playqueue/VLCPlayQueueModel.m
> @@ -90,5 +90,10 @@ - (void)updateItemAtIndex:(size_t)index
>     VLCPlayQueueItem * const item = _playQueueArray[index];
>     [item updateRepresentation];
> }
> -
> +- (void)replaceItemAtIndex:(size_t)index withItem:(VLCPlayQueueItem *)newItem
> +{
> +    if (index < _playQueueArray.count) {
> +        [_playQueueArray replaceObjectAtIndex:index withObject:newItem];
> +    }
> +}
> @end
> diff --git a/modules/gui/macosx/playqueue/VLCPlayQueueTableCellView.m b/modules/gui/macosx/playqueue/VLCPlayQueueTableCellView.m
> index b97c7e9b62..ef0e69380b 100644
> --- a/modules/gui/macosx/playqueue/VLCPlayQueueTableCellView.m
> +++ b/modules/gui/macosx/playqueue/VLCPlayQueueTableCellView.m
> @@ -28,6 +28,7 @@
> #import "extensions/NSString+Helpers.h"
> 
> #import "library/VLCLibraryImageCache.h"
> +#import "library/VLCInputItem.h"
> 
> #import "main/VLCMain.h"
> 
> @@ -35,6 +36,7 @@
> 
> #import "views/VLCImageView.h"
> 
> +#import <vlc_common.h>
> #import <vlc_configuration.h>
> 
> @implementation VLCPlayQueueTableCellView
> @@ -91,6 +93,16 @@ - (void)setRepresentedPlayQueueItem:(VLCPlayQueueItem *)item
> 
>     const BOOL validArtistString = item.artistName && item.artistName.length > 0;
>     const BOOL validAlbumString = item.albumName && item.albumName.length > 0;
> +    const BOOL validTitleString = item.inputItem && item.inputItem.title && (item.inputItem.title.length > 0);
> +
> +    NSString *playTitle = item.title;
> +    if (validTitleString) {
> +        if (item.inputItem.trackNumber && item.inputItem.trackNumber.length >0) {
> +            playTitle = [NSString stringWithFormat:@"%@ · %@", item.inputItem.trackNumber, item.inputItem.title];
> +        } else {
> +            playTitle = item.inputItem.title;
> +        }
> +    }
> 
>     NSString *songDetailString = @"";
> 
> @@ -104,7 +116,7 @@ - (void)setRepresentedPlayQueueItem:(VLCPlayQueueItem *)item
>         self.mediaTitleTextField.hidden = YES;
>         self.secondaryMediaTitleTextField.hidden = NO;
>         self.artistTextField.hidden = NO;
> -        self.secondaryMediaTitleTextField.stringValue = item.title;
> +        self.secondaryMediaTitleTextField.stringValue = playTitle;
>         self.artistTextField.stringValue = songDetailString;
>         self.audioMediaTypeIndicator.hidden = NO;
> 
> @@ -114,7 +126,7 @@ - (void)setRepresentedPlayQueueItem:(VLCPlayQueueItem *)item
>         self.mediaTitleTextField.hidden = NO;
>         self.secondaryMediaTitleTextField.hidden = YES;
>         self.artistTextField.hidden = YES;
> -        self.mediaTitleTextField.stringValue = item.title;
> +        self.mediaTitleTextField.stringValue = playTitle;
>         self.audioMediaTypeIndicator.hidden = YES;
> 
>         self.audioArtworkImageView.hidden = YES;
> -- 
> 2.39.5 (Apple Git-154)
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel



More information about the vlc-devel mailing list