Streaming

RSS for tag

Deep dive into the technical specifications that influence seamless playback for streaming services, including bitrates, codecs, and caching mechanisms.

Streaming Documentation

Post

Replies

Boosts

Views

Activity

verify_ckc no longer works
Hello there, I understand most components of the FairPlay Streaming Server SDK haven't been updated in about a decade, but the verify_ckc tool no longer works, and it's really helpful. It throws errors when trying to import the Crypto library...probably something to do with this whole Python 2 vs Python 3 thing. I don't know anything about Python or I'd try to fix it myself but...I'm just bringing this up in case anyone from the FairPlay team reads these things! Thx
0
0
546
Feb ’24
SK..R1 integrity bytes do not match the value in SKR1 Integrity tag
Hi I am trying to implement D Function in python. import hashlib from Crypto.Cipher import AES from Crypto.Hash import SHA from Crypto.Util.Padding import pad as padding from Crypto.PublicKey import RSA PRIME = 813416437 NB_RD = 16 def dfunction(R2, ASk): tmp = bytearray(20) pad = bytearray(64) MBlock = [0] * 14 P = PRIME if len(R2) >= 56: return -1 # kDRMSKDServerParamErr # Padding until a multiple of 56B pad[:len(R2)] = R2 pad[len(R2)] = 0x80 pad[len(R2) + 1:56] = [0] * (56 - len(R2) - 1) # Create 14 32b values for i in range(14): MBlock[i] = (pad[4 * i] << 24) ^ (pad[4 * i + 1] << 16) ^ (pad[4 * i + 2] << 8) ^ pad[4 * i + 3] # Reunify into 2 32 bits values #MBlock[0] += sum(MBlock[1:7]) #MBlock[1] = 0 #MBlock[1] += sum(MBlock[7:]) # Reunify into 2 32 bits values for i in range(1, 7): MBlock[0] += MBlock[i] MBlock[1] = 0 for i in range(7): MBlock[1] += MBlock[i + 7] # Apply the function (C_r) for i in range(2): for r in range(NB_RD): if MBlock[i] & 1: MBlock[i] >>= 1 else: MBlock[i] = (3 * MBlock[i] + 1) % P # Append to M for i in range(4): pad[56 + i] = (MBlock[0] >> (8 * i)) & 0xFF pad[60 + i] = (MBlock[1] >> (8 * i)) & 0xFF h = hashlib.sha1() h.update(pad) hh = h.digest()[:16] cipher = AES.new(ASk, AES.MODE_ECB) DASk = cipher.encrypt(padding(hh, AES.block_size)) return DASk Then, i am trying to match integrities and they does not match. I think there is an mistake in D Function implementation. Any clue whats wrong? Thank you
0
0
522
Feb ’24
How to retrieve the playback state
Per FP Streaming programming guide, The SPC includes a specific TLLV to provide the state of the media content playback. And total value length of this is 16 in decimals. Here i'm trying to retrieve the Playback State. which is of 20-23 ByteRange. byte[] mediaPlaybackStateBlock = getBlock(MEDIA_PLAYBACK_STATE).getValueData(); playbackState = Arrays.copyOfRange(mediaPlaybackStateBlock, 20, 24); I'm endup in issue - arraycopy: length -4 is negative. I'm bit confused on how to retrieve the playback state from 20-23 ByteRange when its length jus 16.. Kindly clarify
0
0
468
Jan ’24
Use of Fairplay Streaming Test Streams with the Apple FPS Client sample code
Hello all, I am a completely new to iOS development, and I need to make an app that will be playing encrypted content using Fairplay. Right now I am using the Sample client in the latest FPS Server SDK (HLSCatalog), and from what I understand the default sources in Streams.plist are not protected. There's an entry with is_protected=YES and where I can replace the playlist_url, but I was wondering if I could use the .m3u8 files in the FPS Test Content found at https://developer.apple.com/streaming/fps/ ? If so, I don't really know how to. In one of the .m3u8 files of the Test Content, I could find the "content_key_id_list" example value that's also mentioned in the client's README (skd://twelve), which is why I'm asking. Thanks in advance!
0
0
642
Jan ’24
AppleCoreMedia 1.0.0.21B101 always requesting 2 streams from ABR
Hi Team, We see an issue with this version if CoreMedia requesting multiple qualities at all times for a stream. We don't see this issue on 1.0.0.21C62. We are unsure what would be causing this. [2024-01-05 16:53:51] "GET /live/cinecanal/live/cinecanal_720p/video.m3u8?_HLS_msn=630&_HLS_part=0 HTTP/1.0" 200 1145 2529 1090199 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:52] "GET /live/cinecanal/live/cinecanal_1080p/audio.m3u8?_HLS_msn=630&_HLS_part=0 HTTP/1.0" 200 1146 2396 1013356 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:52] "GET /live/cinecanal/live/cinecanal_1080p/a_1459_2452140264_630_0.fmp4 HTTP/1.0" 200 1139 24975 1013385 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:52] "GET /live/cinecanal/live/cinecanal_720p/video.m3u8?_HLS_msn=630&_HLS_part=1 HTTP/1.0" 200 1145 2603 998670 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:52] "GET /live/cinecanal/live/cinecanal_720p/v_1058_2452140000_630_1.fmp4 HTTP/1.0" 200 1138 40534 998739 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:53] "GET /live/cinecanal/live/cinecanal_720p/video.m3u8?_HLS_msn=630&_HLS_part=2 HTTP/1.0" 200 1145 2677 835327 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:53] "GET /live/cinecanal/live/cinecanal_720p/v_1058_2452140000_630_2.fmp4 HTTP/1.0" 200 1138 57656 835207 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:53] "GET /live/cinecanal/live/cinecanal_1080p/audio.m3u8?_HLS_msn=630&_HLS_part=1 HTTP/1.0" 200 1146 2458 986038 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:53] "GET /live/cinecanal/live/cinecanal_1080p/a_1459_2452140264_630_1.fmp4 HTTP/1.0" 200 1139 24700 986032 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:54] "GET /live/cinecanal/live/cinecanal_720p/video.m3u8?_HLS_msn=630&_HLS_part=3 HTTP/1.0" 200 1145 2751 1013257 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:54] "GET /live/cinecanal/live/cinecanal_720p/v_1058_2452140000_630_3.fmp4 HTTP/1.0" 200 1138 55900 1013324 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:54] "GET /live/cinecanal/live/cinecanal_1080p/audio.m3u8?_HLS_msn=630&_HLS_part=2 HTTP/1.0" 200 1146 2520 1016693 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:54] "GET /live/cinecanal/live/cinecanal_1080p/a_1459_2452140264_630_2.fmp4 HTTP/1.0" 200 1139 25014 1016717 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:55] "GET /live/cinecanal/live/cinecanal_720p/video.m3u8?_HLS_msn=630&_HLS_part=4 HTTP/1.0" 200 1145 2825 917753 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:55] "GET /live/cinecanal/live/cinecanal_720p/v_1058_2452140000_630_4.fmp4 HTTP/1.0" 200 1138 103745 917903 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:55] "GET /live/cinecanal/live/cinecanal_1080p/audio.m3u8?_HLS_msn=630&_HLS_part=3 HTTP/1.0" 200 1146 2582 958102 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:55] "GET /live/cinecanal/live/cinecanal_1080p/a_1459_2452140264_630_3.fmp4 HTTP/1.0" 200 1139 24782 958195 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:56] "GET /live/cinecanal/live/cinecanal_720p/video.m3u8?_HLS_msn=630&_HLS_part=5 HTTP/1.0" 200 1145 2899 931101 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:56] "GET /live/cinecanal/live/cinecanal_720p/v_1058_2452140000_630_5.fmp4 HTTP/1.0" 200 1138 112113 931228 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:56] "GET /live/cinecanal/live/cinecanal_1080p/audio.m3u8?_HLS_msn=630&_HLS_part=4 HTTP/1.0" 200 1146 2644 935550 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:56] "GET /live/cinecanal/live/cinecanal_1080p/a_1459_2452140264_630_4.fmp4 HTTP/1.0" 200 1139 24824 937720 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:57] "GET /live/cinecanal/live/cinecanal_1080p/audio.m3u8?_HLS_msn=630&_HLS_part=5 HTTP/1.0" 200 1146 2706 895680 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:57] "GET /live/cinecanal/live/cinecanal_1080p/a_1459_2452140264_630_5.fmp4 HTTP/1.0" 200 1139 24843 895734 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)" [2024-01-05 16:53:57] "GET /live/cinecanal/live/cinecanal_720p/video.m3u8?_HLS_msn=631&_HLS_part=0 HTTP/1.0" 200 1145 2529 907045 "-" "AppleCoreMedia/1.0.0.21B101 (iPhone; U; CPU OS 17_1_2 like Mac OS X; en_us)"
0
0
638
Jan ’24
No audio in generated mpeg4AppleHLS by AVAssetWriter
I'm trying to use AVCaptureSession and AVAssetWriter to convert video and audio from an iPhone's camera and microphone into a fragmented video file in AppleHLS format. Below is part of the code. It seems that the capture is successful, and I have confirmed that the data received with captureOutput() can be appended to videoWriterIput and audioWriterInput using append(). When executing audioWriterInput!.append(sampleBuffer), sampleBuffer has the following value, and it looks like the audio data has been passed to AssetWriter. sampleBuffer.duration : CMTime(value: 941, timescale: 44100, flags: __C.CMTimeFlags(rawValue: 1), epoch: 0) sampleBuffer.totalSampleSize : 1882 However, the final output init.mp4 and *.m4s do not contain Audio. (The video can be played without any problems.) Could you please tell me any problems or hints as to why Audio is not included? /// Capture Session let captureSession = AVCaptureSession() /// Capture Input var videoDevice: AVCaptureDevice? var audioDevice: AVCaptureDevice? /// Configure and Start Capture Session func startCapture() { // Start Configuration captureSession.beginConfiguration() // Setup Input Video videoDevice = self.defaultCamera(cameraSide: cameraSide) videoDevice!.activeVideoMinFrameDuration = CMTimeMake(value: 1, timescale: 30) let videoInput = try AVCaptureDeviceInput(device: videoDevice!) as AVCaptureDeviceInput captureSession.addInput(videoInput) // Setup Input Audio audioDevice = AVCaptureDevice.default(for: AVMediaType.audio) let audioInput = try AVCaptureDeviceInput(device: audioDevice!) as AVCaptureDeviceInput captureSession.addInput(audioInput) // Setup Output Video let videoDataOutput = AVCaptureVideoDataOutput() videoDataOutput.setSampleBufferDelegate(self, queue: recordingQueue) videoDataOutput.alwaysDiscardsLateVideoFrames = true videoDataOutput.videoSettings = [ kCVPixelBufferPixelFormatTypeKey: Int(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)] as [String : Any] captureSession.addOutput(videoDataOutput) // Setup Output Audio let audioDataOutput = AVCaptureAudioDataOutput() audioDataOutput.setSampleBufferDelegate(self, queue: recordingQueue) captureSession.addOutput(audioDataOutput) //End Configuration captureSession.commitConfiguration() // Start Capture captureSession.startRunning() } private let assetWriter: AVAssetWriter? private let startTimeOffset: CMTime private var audioWriterInput: AVAssetWriterInput? private let videoWriterInput: AVAssetWriterInput? func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { if assetWriter == nil { // AssetWriter assetWriter = AVAssetWriter(contentType: UTType(AVFileType.mp4.rawValue)!) self.startTimeOffset = CMTime(value: 1, timescale: 1) // Setup Input of Audio. let audioCompressionSettings: [String: Any] = [ AVFormatIDKey: kAudioFormatMPEG4AAC, AVSampleRateKey: 44_100, AVNumberOfChannelsKey: 1, AVEncoderBitRateKey: 128_000 ] audioWriterInput = AVAssetWriterInput(mediaType: .audio, outputSettings: audioCompressionSettings) audioWriterInput!.expectsMediaDataInRealTime = true assetWriter.add(audioWriterInput!) // Setup Input of Video. let videoCompressionSettings: [String: Any] = [ AVVideoCodecKey: AVVideoCodecType.h264 ] let videoCompressionSettings: [String: Any] = [ AVVideoCodecKey: AVVideoCodecType.h264, AVVideoWidthKey: 1280, AVVideoHeightKey: 720, AVVideoCompressionPropertiesKey: [ kVTCompressionPropertyKey_AverageBitRate: 1_024_000, kVTCompressionPropertyKey_ProfileLevel: kVTProfileLevel_H264_Baseline_AutoLevel ] ] videoWriterInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoCompressionSettings) videoWriterInput!.expectsMediaDataInRealTime = true pixelBuffer = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: videoWriterInput!, sourcePixelBufferAttributes: [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]) assetWriter.add(videoWriterInput!) // Configure the asset writer for writing data in fragmented MPEG-4 format. assetWriter.outputFileTypeProfile = AVFileTypeProfile.mpeg4AppleHLS assetWriter.preferredOutputSegmentInterval = CMTime(seconds: 1.0, preferredTimescale: 1) assetWriter.initialSegmentStartTime = startTimeOffset assetWriter.delegate = self // start AssetWriiter startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) assetWriter.startWriting() assetWriter.startSession(atSourceTime: startTime) } let isVideo = output is AVCaptureVideoDataOutput if isVideo { if videoWriterInput.isReadyForMoreMediaData { videoWriterInput!.append(sampleBuffer) } }else{ if audioWriterInput!.isReadyForMoreMediaData { audioWriterInput!.append(sampleBuffer) } } } func assetWriter(_ writer: AVAssetWriter, didOutputSegmentData segmentData: Data, segmentType: AVAssetSegmentType, segmentReport: AVAssetSegmentReport?) { : : }
0
0
543
Dec ’23
Issue in playing fairplay video
We have to play some encrypted videos from server. In AVAssetResourceLoaderDelegate we got the ckc data correctly and responded with that. Then video just starts playing and stops immdediately. When we check the playerItem error description we got Error Domain=AVFoundationErrorDomain Code=-11819 "Cannot Complete Action" UserInfo={NSLocalizedDescription=Cannot Complete Action, NSLocalizedRecoverySuggestion=Try again later.}. Any one encountered this?
0
0
506
Dec ’23
Stereo video HLS
I am trying to set up HLS with MV HEVC. I have an MV HEVC MP4 converted with AVAssetWriter that plays as a "spatial video" in Photos in the simulator. I've used ffmpeg to fragment the video for HLS (sample m3u8 file below). The HLS of the mp4 plays on a VideoMaterial with an AVPlayer in the simulator, but it is hard to determine if the streamed video is stereo. Is there any guidance on confirming that the streamed mp4 video is properly being read as stereo? Additionally, I see that REQ-VIDEO-LAYOUT is required for multivariant HLS. However if there is ONLY stereo video in the playlist is it needed? Are there any other configurations need to make the device read as stereo? Sample m3u8 playlist #EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:13 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:12.512500, sample_video0.ts #EXTINF:8.341667, sample_video1.ts #EXTINF:12.512500, sample_video2.ts #EXTINF:8.341667, sample_video3.ts #EXTINF:8.341667, sample_video4.ts #EXTINF:12.433222, sample_video5.ts #EXT-X-ENDLIST
5
1
1.7k
Dec ’23
IDR keyframes now required by Safari (as of iOS 16.3.1?)
Can we confirm that as of iOS 16.3.1, key frames for MPEGTS via HLS are mandatory now? I've been trying to figure out why https://chaney-field3.click2stream.com/ shows "Playback Error" across Safari, Chrome, Firefox, etc.. I ran the diagnostics against one of the m3u8 files that is generated via Developer Tools (e.g. mediastreamvalidator "https://e1-na7.angelcam.com/cameras/102610/streams/hls/playlist.m3u8?token=" and then hlsreport validation_data.json) and see this particular error: Video segments MUST start with an IDR frame Variant #1, IDR missing on 3 of 3 Does Safari and iOS devices explicitly block playback when it doesn't find one? From what I understand AngelCam simply acts as a passthrough for the video/audio packets and does no transcoding but converts the RTSP packets into HLS for web browsers But IP cameras are constantly streaming their data and a user connecting to the site may be receiving the video between key frames, so it would likely violate this expectation. From my investigation it also seems like this problem also started happening in iOS 16.3? I'm seeing similar reports for other IP cameras here: https://ipcamtalk.com/threads/blue-iris-ui3.23528/page-194#post-754082 https://www.reddit.com/r/BlueIris/comments/1255d78/ios_164_breaks_ui3_video_decode/ For what it's worth, when I re-encoded the MPEG ts files (e.g. ffmpeg-i /tmp/streaming-master-m4-na3.bad/segment-375.ts -c:v h264 /tmp/segment-375.ts) it strips the non key frames in the beginning and then playback works properly if I host the same images on a static site and have the iOS device connect to it. It seems like Chrome, Firefox, VLC, and ffmpeg are much more forgiving on missing key frames. I'm wondering what the reason for enforcing this requirement? And can I confirm it's been a recent change?
1
0
541
Dec ’23
FairPlay and Extended Clear Lead
We're experimenting with a stream that has a large (10 minutes) clear portion in front of the protected section w/Fairplay. We're noticing that AVPlayer/Safari trigger calls to fetch the license key even while it's playing the clear part, and once we provide the key, playback fails with: name = AVPlayerItemFailedToPlayToEndTimeNotification, object = Optional(<AVPlayerItem: 0x281ff2800> I/NMU [No ID]), userInfo = Optional([AnyHashable("AVPlayerItemFailedToPlayToEndTimeErrorKey"): Error Domain=CoreMediaErrorDomain Code=-12894 "(null)"]) - name : "AVPlayerItemFailedToPlayToEndTimeNotification" - object : <AVPlayerItem: 0x281ff2800> I/NMU [No ID] ▿ userInfo : 1 element ▿ 0 : 2 elements ▿ key : AnyHashable("AVPlayerItemFailedToPlayToEndTimeErrorKey") - value : "AVPlayerItemFailedToPlayToEndTimeErrorKey" - value : Error Domain=CoreMediaErrorDomain Code=-12894 "(null)" It seems like AVPlayer is trying to decrypt the clear portion of the stream...and I'm wondering if it's because we've set up our manifest incorrectly. Here it is: #EXTM3U #EXT-X-VERSION:8 #EXT-X-TARGETDURATION:20 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-INDEPENDENT-SEGMENTS #EXT-X-PLAYLIST-TYPE:VOD #EXT-X-MAP:URI="clear-asset.mp4",BYTERANGE="885@0" #EXT-X-DEFINE:NAME="path0",VALUE="clear-asset.mp4" #EXTINF:9.98458, #EXT-X-BYTERANGE:81088@885 {$path0} #EXTINF:19.96916, #EXT-X-BYTERANGE:159892@81973 {$path0} #EXTINF:19.96916, #EXT-X-BYTERANGE:160245@241865 {$path0} #EXT-X-DISCONTINUITY #EXT-X-MAP:URI="secure-asset.mp4",BYTERANGE="788@0" #EXT-X-DEFINE:NAME="path1",VALUE="secure-asset.mp4" #EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://guid",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1" #EXTINF:19.96916, #EXT-X-BYTERANGE:159928@5196150 {$path1} #EXT-X-ENDLIST
0
0
470
Dec ’23
Playing Offline HLS Content with AES-128 encryption on iOS
Hi Team, Offline playback with AES-128 encryption I'm downloading HLS content that is AES-128 encrypted and using the AVAssetResourceLoaderDelegate method shouldWaitForLoadingOfRequestedResource to parse the manifest to fetch the AES key URL. After fetching the key URL, I'll download and save the AES key locally. I will use the locally saved key to start the offline playback. Since AVContentKeySession has been there for quite some time, is it okay to use the resource loader delegate method to parse and download the AES key? Is there any chance that Apple will deprecate the downloading keys through the resource loader delegate? Thanks, Deepak.N
0
0
475
Nov ’23
mediafilesegmenter error with hvc1
I'm using mediafilesegmenter with input as a fragmented mp4 hvc1 file and got this error: Nov 23 2023 17:48:25.948: Fragmented MP4 is the only supported container format for the segmentation of HEVC content Nov 23 2023 17:48:25.948: Unsupported media type 'hvc1' in track 0 Nov 23 2023 17:48:25.948: Unable to find any valid tracks to segment. Segmenting failed (-12780).
2
1
783
Nov ’23
ContentKeyDelegate functions not being called in iOS 17
Hello, I'm having an issue where my app is in TestFlight, and some of my testers are reporting that FairPlay protected videos are not playing back in iOS 17. It's been working fine in iOS 16 (my app's initial target). I can see from the debug logs that for an online stream request - contentKeySession(_ session: AVContentKeySession, didProvide keyRequest: AVContentKeyRequest) is never called. Whereas, a download for offline playback request, the function is called. I've used much of the sample code in "HLS Catalog With FPS" as part of the FPS developer package. All of my m3u8 files are version 5 and contain encryption instructions like below: #EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://some-uuid",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1" Here's a short excerpt of the code being run: let values = HTTPCookie.requestHeaderFields(with: cookies) let cookieOptions = ["AVURLAssetHTTPHeaderFieldsKey": values] assetUrl = "del\(assetUrl)" clip!.assetUrl = AVURLAsset(url: URL(string: assetUrl)!, options: cookieOptions) clip!.assetUrl!.resourceLoader.setDelegate(self, queue: DispatchQueue.global(qos: .default)) ContentKeyManager.shared.contentKeySession.addContentKeyRecipient(clip!.assetUrl!) urlAssetObserver = self.observe(\.isPlayable, options: [.new, .initial]) { [weak self] (assetUrl, _) in guard let strongSelf = self else { return } strongSelf.playerItem = AVPlayerItem(asset: (self!.clip!.assetUrl)!) strongSelf.player.replaceCurrentItem(with: strongSelf.playerItem) } The error thrown is: Task .<8> finished with error [18,446,744,073,709,550,614] Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL, NSErrorFailingURLStringKey=skd://some-uuid, NSErrorFailingURLKey=skd://some-uuid, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask .<8>" ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<8>, NSUnderlyingError=0x2839a7450 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}} Which I believe is being thrown from AVPlayerItem. Without the delegate, it appears to playback fine. However, I need the delegate (I think), since I'm appending some query params to each request for the segments. I have an observer on the playerItem, per the example project which is changing the status to .failed once he -1002 error is thrown. Please let me know if anything rings to mind to try, or if I can provide any additional info. Thanks in advance!
1
0
752
Nov ’23
Safari native player thumbnails.
I have the m3u8 like this #EXTM3U #EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=190000,BANDWIDTH=240000,RESOLUTION=240x160,FRAME-RATE=24.000,CODECS="avc1.42c01e,mp4a.40.2",CLOSED-CAPTIONS=NONE tracks-v1a1/mono.m3u8?thumbnails=10 #EXT-X-IMAGE-STREAM-INF:BANDWIDTH=10000,RESOLUTION=240x160,CODECS="jpeg",URI="images-240x160/tpl-0-60-10.m3u8?thumbnails=10" and I have no thumbnails in the Safari native player. Could you please tell me why?
0
0
446
Nov ’23