Changeset 251626 in webkit
- Timestamp:
- Oct 25, 2019 7:38:39 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r251625 r251626 1 2019-10-25 Eric Carlson <eric.carlson@apple.com> 2 3 Support for callbacks for manifest events 4 https://bugs.webkit.org/show_bug.cgi?id=202101 5 <rdar://problem/54277362> 6 7 Reviewed by Jer Noble. 8 9 * http/tests/media/resources/hls/metadata/prog_index.m3u8: 10 * http/tests/media/track-in-band-hls-metadata-expected.txt: 11 * http/tests/media/track-in-band-hls-metadata.html: 12 1 13 2019-10-25 Wenson Hsieh <wenson_hsieh@apple.com> 2 14 -
trunk/LayoutTests/http/tests/media/resources/hls/metadata/prog_index.m3u8
r167632 r251626 4 4 #EXT-X-MEDIA-SEQUENCE:0 5 5 #EXT-X-PLAYLIST-TYPE:VOD 6 #EXT-X-DATERANGE:ID="cue-1",START-DATE="2019-01-01T00:00:00.000Z",DURATION=5.000000,X-START-OFFSET="0.000000" 7 #EXT-X-DATERANGE:ID="cue-2",START-DATE="2019-01-01T00:00:05.000Z",DURATION=5.000000,X-END-OFFSET="5.000000" 6 8 #EXTINF:5.00000, 7 9 fileSequence2.ts -
trunk/LayoutTests/http/tests/media/track-in-band-hls-metadata-expected.txt
r196131 r251626 16 16 ** Start playback, wait for all cues to load 17 17 RUN(video.play()) 18 EVENT(cuechange)19 EVENT(cuechange)20 EVENT(cuechange)21 EVENT(cuechange)22 EVENT(cuechange)23 EVENT(cuechange)24 18 25 19 ** Validate cue data 26 20 * 1 27 21 EXPECTED (typeof(cue) != 'undefined') OK 22 EXPECTED (cue.data == 'null') OK 23 EXPECTED (cue.type == 'com.apple.quicktime.HLS') OK 24 EXPECTED (cue.value != 'null') OK 25 EXPECTED (cue.value.key == '"X-START-OFFSET"') OK 26 EXPECTED (cue.value.data == '"0.000000"') OK 27 28 * 2 29 EXPECTED (typeof(cue) != 'undefined') OK 30 EXPECTED (cue.data == 'null') OK 31 EXPECTED (cue.type == 'com.apple.quicktime.HLS') OK 32 EXPECTED (cue.value != 'null') OK 33 EXPECTED (cue.value.key == '"X-END-OFFSET"') OK 34 EXPECTED (cue.value.data == '"5.000000"') OK 35 36 * 3 37 EXPECTED (typeof(cue) != 'undefined') OK 38 EXPECTED (cue.data == 'null') OK 28 39 EXPECTED (cue.type == 'org.id3') OK 29 EXPECTED (cue.data == 'null') OK30 40 EXPECTED (cue.value != 'null') OK 31 41 EXPECTED (cue.value.key == '"TIT2"') OK 32 42 EXPECTED (cue.value.data == '"Stream Counting"') OK 33 43 34 * 244 * 4 35 45 EXPECTED (typeof(cue) != 'undefined') OK 46 EXPECTED (cue.data == 'null') OK 36 47 EXPECTED (cue.type == 'org.id3') OK 37 EXPECTED (cue.data == 'null') OK38 48 EXPECTED (cue.value != 'null') OK 39 49 EXPECTED (cue.value.key == '"TPE1"') OK 40 50 EXPECTED (cue.value.data == '"Andy"') OK 41 51 42 * 352 * 5 43 53 EXPECTED (typeof(cue) != 'undefined') OK 54 EXPECTED (cue.data == 'null') OK 44 55 EXPECTED (cue.type == 'org.id3') OK 45 EXPECTED (cue.data == 'null') OK46 56 EXPECTED (cue.value != 'null') OK 47 57 EXPECTED (cue.value.key == '"TALB"') OK 48 58 EXPECTED (cue.value.data == '"Greatest Hits"') OK 49 59 50 * 460 * 6 51 61 EXPECTED (typeof(cue) != 'undefined') OK 62 EXPECTED (cue.data == 'null') OK 52 63 EXPECTED (cue.type == 'org.id3') OK 53 EXPECTED (cue.data == 'null') OK54 64 EXPECTED (cue.value != 'null') OK 55 65 EXPECTED (cue.value.key == '"GEOB"') OK … … 59 69 EXPECTED (cue.value.name == '"abe.png"') OK 60 70 61 * 571 * 7 62 72 EXPECTED (typeof(cue) != 'undefined') OK 73 EXPECTED (cue.data == 'null') OK 63 74 EXPECTED (cue.type == 'org.id3') OK 64 EXPECTED (cue.data == 'null') OK65 75 EXPECTED (cue.value != 'null') OK 66 76 EXPECTED (cue.value.key == '"APIC"') OK … … 68 78 EXPECTED (cue.value.type == '"image/png"') OK 69 79 70 * 680 * 8 71 81 EXPECTED (typeof(cue) != 'undefined') OK 82 EXPECTED (cue.data == 'null') OK 72 83 EXPECTED (cue.type == 'org.id3') OK 73 EXPECTED (cue.data == 'null') OK74 84 EXPECTED (cue.value != 'null') OK 75 85 EXPECTED (cue.value.key == '"TXXX"') OK … … 77 87 78 88 ** Extract images from cue data, validate by setting img.src 79 RUN(cueImageData = track.cues[ 3].value.data)89 RUN(cueImageData = track.cues[5].value.data) 80 90 EXPECTED (cueImageData instanceof ArrayBuffer == 'true') OK 81 91 RUN(blobUrl = URL.createObjectURL(new Blob([cueImageData], { type: 'image/png' }))) … … 85 95 EXPECTED (imageElement.height == '103') OK 86 96 87 RUN(cueImageData = track.cues[ 4].value.data)97 RUN(cueImageData = track.cues[6].value.data) 88 98 EXPECTED (cueImageData instanceof ArrayBuffer == 'true') OK 89 99 RUN(blobUrl = URL.createObjectURL(new Blob([cueImageData], { type: 'image/png' }))) -
trunk/LayoutTests/http/tests/media/track-in-band-hls-metadata.html
r196131 r251626 12 12 var loadCount = 0; 13 13 var cueData = [ 14 {"key" : "TIT2", "data" : "Stream Counting"}, 15 {"key" : "TPE1", "data" : "Andy"}, 16 {"key" : "TALB", "data" : "Greatest Hits"}, 17 {"key" : "GEOB", "data" : {}, "type" : "image/png", "info" : "Our Hero", "name" : "abe.png"}, 18 {"key" : "APIC", "data" : {}, "type" : "image/png"}, 19 {"key" : "TXXX", "data" : "Text Blob"}, 14 {"key" : "X-START-OFFSET", "keySpace" : "com.apple.quicktime.HLS", "data" : "0.000000"}, 15 {"key" : "X-END-OFFSET", "keySpace" : "com.apple.quicktime.HLS", "data" : "5.000000"}, 16 {"key" : "TIT2", "keySpace" : "org.id3", "data" : "Stream Counting"}, 17 {"key" : "TPE1", "keySpace" : "org.id3", "data" : "Andy"}, 18 {"key" : "TALB", "keySpace" : "org.id3", "data" : "Greatest Hits"}, 19 {"key" : "GEOB", "keySpace" : "org.id3", "data" : {}, "type" : "image/png", "info" : "Our Hero", "name" : "abe.png"}, 20 {"key" : "APIC", "keySpace" : "org.id3", "data" : {}, "type" : "image/png"}, 21 {"key" : "TXXX", "keySpace" : "org.id3", "data" : "Text Blob"}, 20 22 ]; 21 23 var imageSizes = [ [76, 103], [100, 100] ]; … … 44 46 } 45 47 46 testImage( 4);48 testImage(6); 47 49 } 48 50 … … 61 63 observed = JSON.parse(JSON.stringify(observed)); 62 64 for (property in expected) { 65 if (property === "keySpace") 66 continue; 67 63 68 observedValue = observed[property]; 64 69 expectedValue = expected[property]; … … 80 85 function cuechange(event) 81 86 { 82 consoleWrite("EVENT(cuechange)"); 83 if (++cuechangeCount != 6) 87 if (++cuechangeCount != cueData.length) 84 88 return; 85 89 … … 88 92 video.pause(); 89 93 90 for (var i = 0; i < 6; i++) {94 for (var i = 0; i < cueData.length; i++) { 91 95 consoleWrite(`<em>* ${i + 1}</em>`); 92 96 cue = track.cues[i]; 93 97 94 98 testExpected("typeof(cue)", undefined, "!="); 95 testExpected("cue.type", "org.id3");96 99 testExpected("cue.data", null); 100 testExpected("cue.type", cueData[i].keySpace); 97 101 testExpected("cue.value", null, "!="); 98 102 if (typeof(cue.value) == undefined) { … … 108 112 imageElement = document.querySelector("#photo"); 109 113 waitForEvent('load', imageLoad, false, false, imageElement) 110 testImage( 3);114 testImage(5); 111 115 } 112 116 -
trunk/Source/WebCore/ChangeLog
r251623 r251626 1 2019-10-25 Eric Carlson <eric.carlson@apple.com> 2 3 Support for callbacks for manifest events 4 https://bugs.webkit.org/show_bug.cgi?id=202101 5 <rdar://problem/54277362> 6 7 Reviewed by Jer Noble. 8 9 Use AVPlayerItemMetadataCollector to get manifest based time metadata. Use 10 AVPlayerItemMetadataOutput to get time metadata instead of listening for a "timedMetadata" 11 KVO on AVPlayer. 12 13 No new tests, existing test updated. 14 15 * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h: 16 * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm: 17 (WebCore::globalMetadataProcessingQueue): 18 (WebCore::MediaPlayerPrivateAVFoundationObjC::cancelLoad): 19 (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayerItem): 20 (WebCore::metadataType): 21 (WebCore::MediaPlayerPrivateAVFoundationObjC::metadataGroupDidArrive): 22 (WebCore::MediaPlayerPrivateAVFoundationObjC::metadataDidArrive): 23 (WebCore::itemKVOProperties): 24 (-[WebCoreAVFMovieObserver observeValueForKeyPath:ofObject:change:context:]): 25 (-[WebCoreAVFMovieObserver metadataOutput:didOutputTimedMetadataGroups:fromPlayerItemTrack:]): 26 (-[WebCoreAVFMovieObserver metadataCollector:didCollectDateRangeMetadataGroups:indexesOfNewGroups:indexesOfModifiedGroups:]): 27 1 28 2019-10-25 Andy Estes <aestes@apple.com> 2 29 -
trunk/Source/WebCore/PAL/ChangeLog
r251623 r251626 1 2019-10-25 Eric Carlson <eric.carlson@apple.com> 2 3 Support for callbacks for manifest events 4 https://bugs.webkit.org/show_bug.cgi?id=202101 5 <rdar://problem/54277362> 6 7 Reviewed by Jer Noble. 8 9 * pal/cocoa/AVFoundationSoftLink.h: 10 * pal/cocoa/AVFoundationSoftLink.mm: 11 1 12 2019-10-25 Andy Estes <aestes@apple.com> 2 13 -
trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.h
r244704 r251626 63 63 SOFT_LINK_CLASS_FOR_HEADER(PAL, AVPlayerItem) 64 64 SOFT_LINK_CLASS_FOR_HEADER(PAL, AVPlayerItemLegibleOutput) 65 SOFT_LINK_CLASS_FOR_HEADER(PAL, AVPlayerItemMetadataCollector) 66 SOFT_LINK_CLASS_FOR_HEADER(PAL, AVPlayerItemMetadataOutput) 65 67 SOFT_LINK_CLASS_FOR_HEADER(PAL, AVPlayerItemVideoOutput) 66 68 SOFT_LINK_CLASS_FOR_HEADER(PAL, AVPlayerLayer) … … 232 234 SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVMetadataKeySpaceISOUserData, NSString *) 233 235 #define AVMetadataKeySpaceISOUserData PAL::get_AVFoundation_AVMetadataKeySpaceISOUserData() 236 SOFT_LINK_CONSTANT_FOR_HEADER(PAL, AVFoundation, AVMetadataKeySpaceHLSDateRange, NSString *) 237 #define AVMetadataKeySpaceHLSDateRange PAL::get_AVFoundation_AVMetadataKeySpaceHLSDateRange() 234 238 235 239 #if PLATFORM(MAC) -
trunk/Source/WebCore/PAL/pal/cocoa/AVFoundationSoftLink.mm
r244704 r251626 55 55 SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVPlayerItem, PAL_EXPORT) 56 56 SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVPlayerItemLegibleOutput, PAL_EXPORT) 57 SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVPlayerItemMetadataCollector, PAL_EXPORT) 58 SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVPlayerItemMetadataOutput, PAL_EXPORT) 57 59 SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVPlayerItemVideoOutput, PAL_EXPORT) 58 60 SOFT_LINK_CLASS_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVPlayerLayer, PAL_EXPORT) … … 111 113 SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVMetadataCommonKeyTitle, NSString *, PAL_EXPORT) 112 114 SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVMetadataKeySpaceCommon, NSString *, PAL_EXPORT) 115 SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVMetadataKeySpaceHLSDateRange, NSString *, PAL_EXPORT) 113 116 SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVMetadataKeySpaceID3, NSString *, PAL_EXPORT) 114 117 SOFT_LINK_CONSTANT_FOR_SOURCE_WITH_EXPORT(PAL, AVFoundation, AVMetadataKeySpaceISOUserData, NSString *, PAL_EXPORT) -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
r247800 r251626 40 40 OBJC_CLASS AVPlayerItem; 41 41 OBJC_CLASS AVPlayerItemLegibleOutput; 42 OBJC_CLASS AVPlayerItemMetadataCollector; 43 OBJC_CLASS AVPlayerItemMetadataOutput; 42 44 OBJC_CLASS AVPlayerItemVideoOutput; 43 45 OBJC_CLASS AVPlayerLayer; … … 117 119 void rateDidChange(double); 118 120 void timeControlStatusDidChange(int); 121 void metadataGroupDidArrive(const RetainPtr<NSArray>&, const MediaTime&); 119 122 void metadataDidArrive(const RetainPtr<NSArray>&, const MediaTime&); 120 123 void firstFrameAvailableDidChange(bool); … … 156 159 #endif 157 160 161 MediaTime currentMediaTime() const override; 162 158 163 private: 159 164 // engine support … … 170 175 void platformPause() override; 171 176 bool platformPaused() const override; 172 MediaTime currentMediaTime() const override;173 177 void setVolume(float) override; 174 178 void setMuted(bool) override; … … 411 415 #endif 412 416 #endif 417 418 RetainPtr<AVPlayerItemMetadataCollector> m_metadataCollector; 419 RetainPtr<AVPlayerItemMetadataOutput> m_metadataOutput; 413 420 414 421 mutable RetainPtr<NSArray> m_cachedSeekableRanges; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
r250566 r251626 175 175 } 176 176 177 @interface WebCoreAVFMovieObserver : NSObject <AVPlayerItemLegibleOutputPushDelegate >177 @interface WebCoreAVFMovieObserver : NSObject <AVPlayerItemLegibleOutputPushDelegate, AVPlayerItemMetadataOutputPushDelegate, AVPlayerItemMetadataCollectorPushDelegate> 178 178 { 179 179 WeakPtr<MediaPlayerPrivateAVFoundationObjC> m_player; … … 188 188 - (void)legibleOutput:(id)output didOutputAttributedStrings:(NSArray *)strings nativeSampleBuffers:(NSArray *)nativeSamples forItemTime:(CMTime)itemTime; 189 189 - (void)outputSequenceWasFlushed:(id)output; 190 - (void)metadataCollector:(AVPlayerItemMetadataCollector *)metadataCollector didCollectDateRangeMetadataGroups:(NSArray<AVDateRangeMetadataGroup *> *)metadataGroups indexesOfNewGroups:(NSIndexSet *)indexesOfNewGroups indexesOfModifiedGroups:(NSIndexSet *)indexesOfModifiedGroups; 191 - (void)metadataOutput:(AVPlayerItemMetadataOutput *)output didOutputTimedMetadataGroups:(NSArray<AVTimedMetadataGroup *> *)groups fromPlayerItemTrack:(AVPlayerItemTrack *)track; 190 192 @end 191 193 … … 436 438 [m_avPlayerItem.get() removeOutput:m_legibleOutput.get()]; 437 439 m_legibleOutput = nil; 440 } 441 442 if (m_metadataCollector) { 443 // FIXME - removeMediaDataCollector sometimes crashes, do not uncomment this until rdar://56617504 has been fixed. 444 // if (m_avPlayerItem) 445 // [m_avPlayerItem.get() removeMediaDataCollector:m_metadataCollector.get()]; 446 m_metadataCollector = nil; 447 } 448 449 if (m_metadataOutput) { 450 if (m_avPlayerItem) 451 [m_avPlayerItem.get() removeOutput:m_metadataOutput.get()]; 452 m_metadataOutput = nil; 438 453 } 439 454 … … 940 955 setAVPlayerItem(m_avPlayerItem.get()); 941 956 942 const NSTimeInterval legibleOutputAdvanceInterval = 2;957 const NSTimeInterval avPlayerOutputAdvanceInterval = 2; 943 958 944 959 RetainPtr<NSArray> subtypes = adoptNS([[NSArray alloc] initWithObjects:[NSNumber numberWithUnsignedInt:kCMSubtitleFormatType_WebVTT], nil]); … … 947 962 948 963 [m_legibleOutput.get() setDelegate:m_objcObserver.get() queue:dispatch_get_main_queue()]; 949 [m_legibleOutput.get() setAdvanceIntervalForDelegateInvocation: legibleOutputAdvanceInterval];964 [m_legibleOutput.get() setAdvanceIntervalForDelegateInvocation:avPlayerOutputAdvanceInterval]; 950 965 [m_legibleOutput.get() setTextStylingResolution:AVPlayerItemLegibleOutputTextStylingResolutionSourceAndRulesOnly]; 951 966 [m_avPlayerItem.get() addOutput:m_legibleOutput.get()]; … … 961 976 createVideoOutput(); 962 977 #endif 978 979 m_metadataCollector = adoptNS([PAL::allocAVPlayerItemMetadataCollectorInstance() initWithIdentifiers:nil classifyingLabels:nil]); 980 [m_metadataCollector.get() setDelegate:m_objcObserver.get() queue:dispatch_get_main_queue()]; 981 [m_avPlayerItem.get() addMediaDataCollector:m_metadataCollector.get()]; 982 983 m_metadataOutput = adoptNS([PAL::allocAVPlayerItemMetadataOutputInstance() initWithIdentifiers:nil]); 984 [m_metadataOutput.get() setDelegate:m_objcObserver.get() queue:dispatch_get_main_queue()]; 985 [m_metadataOutput.get() setAdvanceIntervalForDelegateInvocation:avPlayerOutputAdvanceInterval]; 986 [m_avPlayerItem.get() addOutput:m_metadataOutput.get()]; 963 987 964 988 setDelayCallbacks(false); … … 2973 2997 2974 2998 #if ENABLE(DATACUE_VALUE) 2975 2976 2999 static const AtomString& metadataType(NSString *avMetadataKeySpace) 2977 3000 { … … 2981 3004 static NeverDestroyed<const AtomString> iTunesMetadata("com.apple.itunes", AtomString::ConstructFromLiteral); 2982 3005 static NeverDestroyed<const AtomString> id3Metadata("org.id3", AtomString::ConstructFromLiteral); 3006 static NeverDestroyed<const AtomString> hlsDateRangeMetadata("com.apple.quicktime.HLS", AtomString::ConstructFromLiteral); 2983 3007 2984 3008 if ([avMetadataKeySpace isEqualToString:AVMetadataKeySpaceQuickTimeUserData]) … … 2992 3016 if ([avMetadataKeySpace isEqualToString:AVMetadataKeySpaceID3]) 2993 3017 return id3Metadata; 3018 if ([avMetadataKeySpace isEqualToString:AVMetadataKeySpaceHLSDateRange]) 3019 return hlsDateRangeMetadata; 2994 3020 2995 3021 return emptyAtom(); 2996 3022 } 2997 2998 #endif 3023 #endif 3024 3025 void MediaPlayerPrivateAVFoundationObjC::metadataGroupDidArrive(const RetainPtr<NSArray>& groups, const MediaTime& currentTime) 3026 { 3027 for (AVDateRangeMetadataGroup *group in groups.get()) { 3028 auto groupStartDate = group.startDate.timeIntervalSince1970; 3029 auto groupEndDate = group.endDate.timeIntervalSince1970; 3030 auto groupDuration = MediaTime::createWithDouble(groupEndDate - groupStartDate); 3031 3032 // A manifest without a #EXT-X-PROGRAM-DATE-TIME won't have a start date, so if currentDate 3033 // is zero assume the metadata items start at the beginning of the stream. 3034 double groupStartTime = 0; 3035 if (auto currentDate = m_avPlayerItem.get().currentDate.timeIntervalSince1970) 3036 groupStartTime = groupStartDate - currentDate - currentTime.toDouble(); 3037 3038 auto groupCopy = adoptNS([[NSMutableArray alloc] init]); 3039 for (AVMetadataItem *item in group.items) { 3040 RetainPtr<AVMutableMetadataItem> itemCopy = adoptNS([item mutableCopy]); 3041 if (!CMTIME_IS_VALID(itemCopy.get().time)) 3042 itemCopy.get().time = CMTimeMakeWithSeconds(groupStartTime, MediaTime::DefaultTimeScale); 3043 if (!CMTIME_IS_VALID(itemCopy.get().duration)) 3044 itemCopy.get().duration = toCMTime(groupDuration); 3045 [groupCopy addObject:itemCopy.get()]; 3046 } 3047 3048 metadataDidArrive(groupCopy, currentTime); 3049 } 3050 } 2999 3051 3000 3052 void MediaPlayerPrivateAVFoundationObjC::metadataDidArrive(const RetainPtr<NSArray>& metadata, const MediaTime& mediaTime) … … 3026 3078 3027 3079 for (AVMetadataItem *item in m_currentMetaData.get()) { 3028 MediaTime start = std::max(PAL::toMediaTime(item.time), MediaTime::zeroTime()); 3080 MediaTime start; 3081 if (CMTIME_IS_VALID(item.time)) 3082 start = std::max(PAL::toMediaTime(item.time), MediaTime::zeroTime()); 3083 3029 3084 MediaTime end = MediaTime::positiveInfiniteTime(); 3030 if (CMTIME_IS_VALID(item.duration)) 3031 end = start + PAL::toMediaTime(item.duration); 3085 auto duration = item.duration; 3086 if (CMTIME_IS_VALID(duration) && CMTimeGetSeconds(duration) > 0.001) 3087 end = start + PAL::toMediaTime(duration); 3032 3088 3033 3089 AtomString type = nullAtom(); … … 3255 3311 @"duration", 3256 3312 @"hasEnabledAudio", 3257 @"timedMetadata",3258 3313 @"canPlayFastForward", 3259 3314 @"canPlayFastReverse", … … 3376 3431 else if ([keyPath isEqualToString:@"duration"]) 3377 3432 player->durationDidChange(PAL::toMediaTime([newValue CMTimeValue])); 3378 else if ([keyPath isEqualToString:@"timedMetadata"] && newValue) { 3379 MediaTime now; 3380 CMTime itemTime = [(AVPlayerItem *)object.get() currentTime]; 3381 if (CMTIME_IS_NUMERIC(itemTime)) 3382 now = std::max(PAL::toMediaTime(itemTime), MediaTime::zeroTime()); 3383 player->metadataDidArrive(RetainPtr<NSArray>(newValue), now); 3384 shouldLogValue = false; 3385 } else if ([keyPath isEqualToString:@"canPlayFastReverse"]) 3433 else if ([keyPath isEqualToString:@"canPlayFastReverse"]) 3386 3434 player->canPlayFastReverseDidChange([newValue boolValue]); 3387 3435 else if ([keyPath isEqualToString:@"canPlayFastForward"]) … … 3450 3498 } 3451 3499 3500 - (void)metadataOutput:(AVPlayerItemMetadataOutput *)output didOutputTimedMetadataGroups:(NSArray<AVTimedMetadataGroup *> *)metadataGroups fromPlayerItemTrack:(AVPlayerItemTrack *)track 3501 { 3502 ASSERT(isMainThread()); 3503 UNUSED_PARAM(output); 3504 UNUSED_PARAM(track); 3505 3506 m_taskQueue.enqueueTask([player = m_player, metadataGroups = retainPtr(metadataGroups), currentTime = m_player->currentMediaTime()] { 3507 if (!player) 3508 return; 3509 3510 for (AVTimedMetadataGroup *group in metadataGroups.get()) 3511 player->metadataDidArrive(retainPtr(group.items), currentTime); 3512 }); 3513 } 3514 3515 - (void)metadataCollector:(AVPlayerItemMetadataCollector *)metadataCollector didCollectDateRangeMetadataGroups:(NSArray<AVDateRangeMetadataGroup *> *)metadataGroups indexesOfNewGroups:(NSIndexSet *)indexesOfNewGroups indexesOfModifiedGroups:(NSIndexSet *)indexesOfModifiedGroups 3516 { 3517 ASSERT(isMainThread()); 3518 UNUSED_PARAM(metadataCollector); 3519 UNUSED_PARAM(indexesOfNewGroups); 3520 UNUSED_PARAM(indexesOfModifiedGroups); 3521 3522 m_taskQueue.enqueueTask([player = m_player, metadataGroups = retainPtr(metadataGroups), currentTime = m_player->currentMediaTime()] { 3523 if (!player) 3524 return; 3525 3526 player->metadataGroupDidArrive(metadataGroups, currentTime); 3527 }); 3528 } 3452 3529 @end 3453 3530 … … 3507 3584 @end 3508 3585 3509 #endif 3586 #endif // HAVE(AVFOUNDATION_LOADER_DELEGATE) 3510 3587 3511 3588 #if HAVE(AVFOUNDATION_VIDEO_OUTPUT) … … 3535 3612 @end 3536 3613 3537 #endif 3538 3539 #endif 3614 #endif // HAVE(AVFOUNDATION_VIDEO_OUTPUT) 3615 3616 #endif
Note: See TracChangeset
for help on using the changeset viewer.