[vlc-commits] [Git][videolan/vlc][master] 2 commits: macosx: fetch now-playing artwork asynchronously

Steve Lhomme (@robUx4) gitlab at videolan.org
Tue Sep 22 02:47:37 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
15eb6e8e by Serhii Bykov at 2026-09-22T02:33:36+00:00
macosx: fetch now-playing artwork asynchronously

- - - - -
12269828 by Serhii Bykov at 2026-09-22T02:33:36+00:00
macosx: guarantee main-queue image-cache completions

- - - - -


3 changed files:

- modules/gui/macosx/library/VLCLibraryImageCache.m
- modules/gui/macosx/menus/VLCStatusBarIcon.m
- modules/gui/macosx/os-integration/VLCRemoteControlService.m


Changes:

=====================================
modules/gui/macosx/library/VLCLibraryImageCache.m
=====================================
@@ -378,7 +378,9 @@ static NSString *thumbnailHashForString(NSString *string)
     if (artworkMRL) {
         NSImage * const cachedImage = [_imageCache objectForKey:artworkMRL];
         if (cachedImage) {
-            completionHandler(cachedImage);
+            dispatch_async(dispatch_get_main_queue(), ^{
+                completionHandler(cachedImage);
+            });
             return;
         }
     }
@@ -402,9 +404,13 @@ static NSString *thumbnailHashForString(NSString *string)
         if (mediaItem.mediaType != VLC_ML_MEDIA_TYPE_AUDIO) {
             [self generateThumbnailForMediaItem:mediaItem.libraryID];
         }
-        completionHandler(_noArtImage);
+        dispatch_async(dispatch_get_main_queue(), ^{
+            completionHandler(self->_noArtImage);
+        });
     } else {
-        completionHandler(_noArtImage);
+        dispatch_async(dispatch_get_main_queue(), ^{
+            completionHandler(self->_noArtImage);
+        });
     }
 }
 
@@ -434,7 +440,9 @@ static NSString *thumbnailHashForString(NSString *string)
     NSString * const cacheKey = [@"flag://" stringByAppendingString:normalizedCountryCode];
     NSImage * const cachedImage = [_imageCache objectForKey:cacheKey];
     if (cachedImage) {
-        completionHandler(cachedImage);
+        dispatch_async(dispatch_get_main_queue(), ^{
+            completionHandler(cachedImage);
+        });
         return;
     }
 
@@ -463,7 +471,9 @@ static NSString *thumbnailHashForString(NSString *string)
 
     NSImage * const cachedImage = [_imageCache objectForKey:cacheKey];
     if (cachedImage) {
-        completionHandler(cachedImage);
+        dispatch_async(dispatch_get_main_queue(), ^{
+            completionHandler(cachedImage);
+        });
         return;
     }
     [self generateImageForInputItem:inputItem withCompletion:completionHandler];


=====================================
modules/gui/macosx/menus/VLCStatusBarIcon.m
=====================================
@@ -28,6 +28,7 @@
 #import "main/VLCMain.h"
 #import "playqueue/VLCPlayQueueController.h"
 #import "playqueue/VLCPlayerController.h"
+#import "library/VLCLibraryImageCache.h"
 #import "library/VLCInputItem.h"
 #import "windows/VLCDetachedAudioWindow.h"
 
@@ -344,7 +345,7 @@
     [self updateCachedURLOfCurrentMedia:inputItem];
 
     if (inputItem) {
-        coverArtImage = [[NSImage alloc] initWithContentsOfURL:inputItem.artworkURL];
+        coverArtImage = NSImage.VLCNoArtImage;
         title = inputItem.title;
         nowPlaying = inputItem.nowPlaying;
         artist = inputItem.artist;
@@ -367,6 +368,18 @@
 
     // Set the metadata in the UI
     [self setMetadataTitle:title artist:artist album:album andCover:coverArtImage];
+
+    if (inputItem) {
+        __weak typeof(self) weakSelf = self;
+        [VLCLibraryImageCache thumbnailForInputItem:inputItem
+                                     withCompletion:^(NSImage * const thumbnail) {
+            VLCStatusBarIcon * const strongSelf = weakSelf;
+            if (!strongSelf || inputItem != playerController.currentMedia) {
+                return;
+            }
+            strongSelf->coverImageView.image = thumbnail ?: NSImage.VLCNoArtImage;
+        }];
+    }
 }
 
 // Update dynamic copy/open menu item status


=====================================
modules/gui/macosx/os-integration/VLCRemoteControlService.m
=====================================
@@ -22,12 +22,14 @@
  *****************************************************************************/
 
 #import <MediaPlayer/MediaPlayer.h>
+#import "extensions/NSImage+VLCAdditions.h"
 
 #import "VLCRemoteControlService.h"
 #import "main/VLCMain.h"
 #import "main/CompatibilityFixes.h"
 #import "playqueue/VLCPlayQueueController.h"
 #import "playqueue/VLCPlayerController.h"
+#import "library/VLCLibraryImageCache.h"
 #import "library/VLCInputItem.h"
 #import "extensions/NSString+Helpers.h"
 
@@ -164,7 +166,7 @@ static inline NSArray * RemoteCommandCenterCommandsToHandle()
 
     NSURL * const artworkURL = inputItem.artworkURL;
     if (artworkURL) {
-        NSImage * const coverArtImage = [[NSImage alloc] initWithContentsOfURL:artworkURL];
+        NSImage * const coverArtImage = NSImage.VLCNoArtImage;
         if (coverArtImage) {
             MPMediaItemArtwork * const mpartwork = [[MPMediaItemArtwork alloc] initWithBoundsSize:coverArtImage.size
                                                                                    requestHandler:^NSImage* _Nonnull(CGSize __unused size) {
@@ -175,6 +177,26 @@ static inline NSArray * RemoteCommandCenterCommandsToHandle()
     }
 
     [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = currentlyPlayingTrackInfo;
+
+    if (artworkURL) {
+        __weak typeof(self) weakSelf = self;
+        [VLCLibraryImageCache thumbnailForInputItem:inputItem
+                                     withCompletion:^(NSImage * const coverArtImage) {
+            VLCRemoteControlService * const strongSelf = weakSelf;
+            if (!strongSelf || inputItem != strongSelf->_playerController.currentMedia) {
+                return;
+            }
+
+            MPMediaItemArtwork * const mpartwork = [[MPMediaItemArtwork alloc] initWithBoundsSize:coverArtImage.size
+                                                                                   requestHandler:^NSImage* _Nonnull(CGSize __unused size) {
+                return coverArtImage;
+            }];
+            MPNowPlayingInfoCenter * const nowPlayingInfoCenter = MPNowPlayingInfoCenter.defaultCenter;
+            NSMutableDictionary * const updatedTrackInfo = [nowPlayingInfoCenter.nowPlayingInfo mutableCopy];
+            updatedTrackInfo[MPMediaItemPropertyArtwork] = mpartwork;
+            nowPlayingInfoCenter.nowPlayingInfo = updatedTrackInfo;
+        }];
+    }
 }
 
 - (void)setTimeInformationForDictionary:(NSMutableDictionary *)dictionary



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6d2e00f0c25065322628592a92993762a4d3c070...12269828660702f997a46594de02c2f58377ef6c

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6d2e00f0c25065322628592a92993762a4d3c070...12269828660702f997a46594de02c2f58377ef6c
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list