[vlc-commits] [Git][videolan/vlc][master] apple: Improve seeking support for Picture in Picture

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Tue Dec 3 18:47:14 UTC 2024



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
0db7de70 by Maxime Chapelet at 2024-12-03T18:34:32+00:00
apple: Improve seeking support for Picture in Picture

Add API to check if media is seekable and update PIP control accordingly
Change API to allow user telling PIP seeking is complete

- - - - -


4 changed files:

- include/vlc/libvlc_media_player.h
- modules/video_output/apple/VLCDrawable.h
- modules/video_output/apple/VLCPictureInPictureController.m
- modules/video_output/apple/vlc_pip_controller.h


Changes:

=====================================
include/vlc/libvlc_media_player.h
=====================================
@@ -928,9 +928,10 @@ bool libvlc_video_set_output_callbacks( libvlc_media_player_t *mp,
  * @protocol VLCPictureInPictureMediaControlling <NSObject>
  * - (void)play;
  * - (void)pause;
- * - (void)seekBy:(int64_t)offset;
+ * - (void)seekBy:(int64_t)offset completion:(dispatch_block_t)completion;;
  * - (int64_t)mediaLength;
  * - (int64_t)mediaTime;
+ * - (BOOL)isMediaSeekable;
  * - (BOOL)isMediaPlaying;
  * @end
  * 


=====================================
modules/video_output/apple/VLCDrawable.h
=====================================
@@ -45,7 +45,8 @@
 
 /// Called by picture in picture to seek with time offset
 /// - Parameter offset: offset duration in milliseconds
-- (void)seekBy:(int64_t)offset;
+/// - Parameter completion: block to call as soon as seek is finished
+- (void)seekBy:(int64_t)offset completion:(dispatch_block_t)completion;
 
 /// Called by picture in picture to get the current media duration
 /// - Returns Must return media duration in milliseconds
@@ -55,6 +56,10 @@
 /// - Returns Must return current media time in milliseconds
 - (int64_t)mediaTime;
 
+/// Called by picture in picture to figure out if media is seekable
+/// - Returns Must return YES if media is seekable, else return NO
+- (BOOL)isMediaSeekable;
+
 /// Called by picture in picture to get the media playback status
 /// - Returns Must return YES if media is playing, else return NO
 - (BOOL)isMediaPlaying;


=====================================
modules/video_output/apple/VLCPictureInPictureController.m
=====================================
@@ -87,6 +87,9 @@ API_AVAILABLE(ios(15.0), tvos(15.0), macosx(12.0))
         [AVPictureInPictureController alloc]
             initWithContentSource:avPipSource
     ];
+    void *mediaController = (__bridge void*)_drawable.mediaController;
+    BOOL isMediaSeekable = (BOOL)_pipcontroller->media_cbs->is_media_seekable(mediaController);
+              avPipController.requiresLinearPlayback = !isMediaSeekable;
     avPipController.delegate = self;
 #if TARGET_OS_IOS
     // Not sure if it's mandatory, its usefulness isn't obvious and 
@@ -169,8 +172,7 @@ API_AVAILABLE(ios(15.0), tvos(15.0), macosx(12.0))
     
     void *mediaController = (__bridge void*)_drawable.mediaController;
     int64_t offset = time_sec * 1e3;
-    _pipcontroller->media_cbs->seek_by(offset, mediaController);
-    completionHandler();
+    _pipcontroller->media_cbs->seek_by(offset, completionHandler, mediaController);
 }
 
 - (BOOL)pictureInPictureControllerIsPlaybackPaused:(AVPictureInPictureController *)pictureInPictureController {
@@ -266,10 +268,10 @@ static void PipControllerMediaPause(void *opaque) {
     [mediaController pause];
 }
 
-static void PipControllerMediaSeekBy(vlc_tick_t time, void *opaque) {
+static void PipControllerMediaSeekBy(vlc_tick_t time, dispatch_block_t completion, void *opaque) {
     id<VLCPictureInPictureMediaControlling> mediaController;
     mediaController = (__bridge id<VLCPictureInPictureMediaControlling>)opaque;
-    [mediaController seekBy:time];
+    [mediaController seekBy:time completion:completion];
 }
 
 static vlc_tick_t PipControllerMediaGetLength(void *opaque) {
@@ -284,6 +286,12 @@ static vlc_tick_t PipControllerMediaGetTime(void *opaque) {
     return [mediaController mediaTime];
 }
 
+static bool PipControllerMediaIsSeekable(void *opaque) {
+    id<VLCPictureInPictureMediaControlling> mediaController;
+    mediaController = (__bridge id<VLCPictureInPictureMediaControlling>)opaque;
+    return (bool)[mediaController isMediaSeekable];
+}
+
 static bool PipControllerMediaIsPlaying(void *opaque) {
     id<VLCPictureInPictureMediaControlling> mediaController;
     mediaController = (__bridge id<VLCPictureInPictureMediaControlling>)opaque;
@@ -320,6 +328,7 @@ static int OpenController( pip_controller_t *pipcontroller )
         PipControllerMediaSeekBy,
         PipControllerMediaGetLength,
         PipControllerMediaGetTime,
+        PipControllerMediaIsSeekable,
         PipControllerMediaIsPlaying
     };
     


=====================================
modules/video_output/apple/vlc_pip_controller.h
=====================================
@@ -27,6 +27,7 @@
 #include <vlc_common.h>
 #include <vlc_tick.h>
 #include <vlc_player.h>
+#include <CoreFoundation/CoreFoundation.h>
 
 typedef struct pip_controller_t pip_controller_t;
 
@@ -41,9 +42,10 @@ struct pip_controller_operations {
 struct pip_controller_media_callbacks {
     void (*play)(void* opaque);
     void (*pause)(void* opaque);
-    void (*seek_by)(vlc_tick_t time, void* opaque);
+    void (*seek_by)(vlc_tick_t time, dispatch_block_t completion, void *opaque);
     vlc_tick_t (*media_length)(void* opaque);
     vlc_tick_t (*media_time)(void* opaque);
+    bool (*is_media_seekable)(void* opaque);
     bool (*is_media_playing)(void* opaque);
 };
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/0db7de70d2185444b1f77211e172f757ae9468b5

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/0db7de70d2185444b1f77211e172f757ae9468b5
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list