I am using AssetPersistenceManager from this Apple Sample : Using AVFoundation to play and persist http live streams
I create an AVURLAsset with a playlist master url, then call downloadStream(for:) with this asset, and the AVAggregateAssetDownloadTask complete download successfully !
It saves a folder named 286943_chapter_01_C955A55455AC0C4E.movpkg which contains the downloaded segments, my .m3u8 file and a StreamInfoBoot.xml file.
The StreamInfoBook.xml file contains references between local segment (or .frag) file and m3u8 segment URL.
However, those urls are signed and generated by Cloudfront. And some times, some URLs inside the .m3u8 file doesn't match URLs in StreamInfoBook.xml because of Expires parameter of cloudfrount.
So I think maybe AVAggregateAssetDownloadTask is calling the .m3u8 file twice : Once to save the .m3u8 and once to download segments and write StreamInfoBook.xml.
Does anyone already faced this issue ? What could I do to check if my Asset is playable offline or not ?
Do you have any suggestion ?
Here is an exemple of not matching segment URLs
In .m3u8 downloaded file :
https: //ezvoiznbov32f.cloudfront.net/file/265579/audio/chapter_08_10.mp3?Expires=1576159816&Signature=vfAYZ8ivP7yKeiranpba3R24gTSxexX4Nb1VjbDrR917pyFQqi2DMMMf8gi3LcueKXxv0FITprXzLXV62Py0Ph4nMxp8ixf5qG5sYnW1JcO74BxNfJE~DEurN~yQgczNBOK4b~bEXrDDZId1AweYJrgjZtjSoyUwAGXf~LA_&Key-Pair-Id=APKAAFEFNOSQQ34Q
In StreamInfoBook.xml file :
https: //ezvoiznbov32f.cloudfront.net/file/265579/audio/chapter_08_10.mp3?Expires=1576159817&Signature=PZ~tqOeIa3Vm26qKTFYU1LCGfvsWNpkUDMi3eFr~EhyRTLj66CDInSwfpoorYjl4Kl4B9eQ1W8ZzTlIMDGvs36wJ235JOszeov23IuIOzAJTlNw7zQYEd4Y1tq~nyZinpFoyDRGk0CelKOhH91Itb3rpQUeMN6lDhO-cq1X1OM_&Key-Pair-Id=APKAAFEFNOSQQ34Q
I'm testing with iOS 13.2
Well, answering myself :
After a very long time trying to make AVAggregateAssetDownloadTask works in background while the application is killed by the system, I finally switched to AVAssetDownloadTask.
Now everything is working perfectly ! It's like magic !
The difference between aggregate and normal tasks is in media selections. But I don't need it for now....
Related
I am playing a file using AVPlayer and it is working fine. What I am looking for is that when the application plays the file it should play as soon as some enough buffer available. Currently what I have noticed is that if the file is big it waits for longer time to start playing the file which means it waits until the file is loaded in the buffer or so.
Any thoughts?
First, thank you Paul, your hint helped.
I have resolved the issue as follow:
Instead of having the URL as the mp3 file; I have created a text file and called it audio.m3u then I have just wrote the url address of my mp3 file in the newly created file (the m3u). Then played the file (audio.m3u) in the AVPlayer.
thats all :)
Sometimes it is useful to download a stream into our local machine.
Reasons could be
To make a manual modification to the manifest
For getting fast access to files of a server with poor networking.
If we try to use curl or wget to download the asset which is pointed by the URL for the stream, we end up downloading a small text file. It is surely not the video asset.
So how can we download the stream itself?
The actual script which does the download is given in the link at the bottom of my answer. But before we proceed to the how-to, let's first understand the steps for downloading a stream.
Without going into too much details, the URL pointing to the stream is typically named with the m3u8 extension. That file is called the manifest of the stream and is actually a text file containing, among other things, a list of pairs: a bitrate and a corresponding URL for the matching playlist file. Here is an excerpt from a manifest file:
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=380600,CODECS="avc1.4d00c,mp4a.40.2",RESOLUTION=320x180
http://f24hls-i.akamaihd.net/hls/live/221193-b/F24_EN_LO_HLS/master_250.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=655600,CODECS="avc1.77.30,mp4a.40.2",RESOLUTION=640x360
http://f24hls-i.akamaihd.net/hls/live/221193/F24_EN_LO_HLS/master_500.m3u8
A playlist file is another text file which tell the player which TS file is to be playing on each position of the playback head.
Here is the beginning of a typical playlist file:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:303165
#EXTINF:10.000,
20170216T114458/master_500/00151/master_500_01165.ts
#EXTINF:10.000,
20170216T114458/master_500/00151/master_500_01166.ts
So after downloading the playlist file for each of the bitrates, we can start downloading the TS files required to play the stream at each of the possible bitrates.
All this is done using a quite simple and self-explaining script which I was putting in GitHub: https://github.com/ishahak/HLS_Downloader
I hope it will be useful for others.
You can simply use ffmpeg. Like this:
fmpeg -i "http://somewhere.com/video.m3u8" -c copy -bsf:a aac_adtstoasc output.mp4
I want to cache the HLS in the ts file.
Apple demo site use custom schema for this site.
https://developer.apple.com/library/ios/samplecode/sc1791/Introduction/Intro.html
This sample use custom schema. But it's use redirect for ts file.
I searched "How to play ts file using the cache in the AVPlayer". I found use redirect local proxy. But it method is prohibited to Apple that the move background.
https://developer.apple.com/library/ios/technotes/tn2277/_index.html#//apple_ref/doc/uid/DTS40010841-CH1-SUBSECTION2
Is it possible to start the ts file cached locally on the AVPlayer ?
As far as I know, Its not possible to play ts files directly using iOS Player (AVPlayer).
But there is a way to play it.
Download the .ts file and save it in app document directory.
Use this library Keemotion/TS2MP4 to
convert ts file to mp4 which can be played using AVPlayer.
Now you can either do it discreetly downloading -> convert -> play for each single file.
or You can download multiple -> convert them to one large mp4 file and play it.
I have a Cordova application that I use to be able to link to mp3 and mp4 files relatively using a src like so:
../../Documents/videos/video.mp4
I just now updated my Cordova application to the latest version and these relative URLs don't work so I've been expermenting with other solutions.
It looks like if I use the cordova.file.documentsDirectory (iOS only) variable I can link to them that way but when I save references to these files in the database the GUID of the application changes and the URL is no longer valid when the app is rebuilt and relaunched.
I tried using cdvfile://localhost/persistent/ but this seems to only work for images and not video or audio files using HTML5 audio and video tags for playback.
Ultimately I could save the files with a variable that gets replaced at run-time but this is obviously not the preferred "solution." Something like [documentsfolder]/videos/video.mp4
How can I link to a persistent file location and have it work with images, audio files, and video files?
I would love to use the cdvfile url but have it work with mp3 and mp4 files.
Thank you.
You should be able to access any resource [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:#"www/[your path]"]
I have a PHP MP3 file which changes every time it is loaded, and plays a different advert, what I would like is away or is there away to play that before the SHOUTcast stream as the SHOUTcast intro file.
I personally dont really want to put it into flash or create custom playlist files but more would like SHOUTcast to fetch an intro file from a URL address.
Unfortunately, the SHOUTcast configuration doesn't allow this directly.
However, you can easily accomplish what you need by having a script pick a new intro file every few seconds or so. Then you can either write that MP3 to the file configured in SHOUTcast, or create a symlink and update it.