AVPlayer, Play a local file URL that is currently being written to? - swift

I have been trying to use a custom AVPlayerItem that lets me copy the currently playing media to file after it has been downloaded while it is streaming into the AVPlayer, essentially letting me cache the displayed video while showing the video as soon as possible.
Unfortunately, my application sometimes needs to download mp4 files from a server (that I don't control) that is giving the mime type as image/gif although the downloaded file IS an mp4 file. Because of this, my AVPlayer is not "streaming" in the video as it's downloaded, and only shows it once the file is completely downloaded and it realizes the file really is an MP4.
My thought is now to just download the file directly to a local file with a .mp4 extension that a standard AVPlayerItem can stream in, and write to this file while reading from it with the AVPlayerItem. Is this possible? Will the AVPlayerItem pause when it is still downloading/buffering the incomplete data or will it just produce an error without displaying anything? Is there a better way I can be doing this?

Related

Saving m3u8 video to disk in swift cocoa

I am trying to save any m3u8 stream playlist as video to disk as 1 complete video file, similar to vlc. I can create an AVAsset and play it in an AVPlayer fine, however the m3u8 links i have tried all return false from asset.isExportable so using AVAssetExportSession does not work. I thought it might be possible opening the link as an InputStream and then writing it to an OutputStream but was lost on how to do this. Is this a viable option or will it only return the actual m3u8 file instead of the .ts video links? Any guidance in the right direction would be appreciated. I am fine doing the research on how to use the different classes, i'm just kinda lost on where to go from here.
Thank you,
Phil
Building a single video from all the streams in a m3u8 playlist may not actually give you what you want, depending on the m3u8 file.
This is because m3u8 playlists can contain multiple bit rate versions for a single video - so if you added them all together you would get the same video with different quality levels (bit rates) one after another.
Its also worth noting that some videos streams will be encrypted, in fact most high value streams such as Netflix etc will be, so downloading them will not allow you to play them back unless you do it as part of the providers own 'download and go' service.
Finally, some services may make it hard for you to access the streams by requiring some form of authentication in parallel with the video stream URL.
Assuming all the above is fine or does not apply in your case, then the video files themselves can be downloaded as files using a HTTP downloading function. Good examples of these exist such as: https://stackoverflow.com/a/35510812/334402

Netstream() progressive download of internal file

Hello All I have been working on a project for a while:
I have a non standard MP4 video file I want to play off a server in a IPhone App (I am using Flash builder to create it).
Due to a combination of server problems (not correctly identifying MIME type and cant be changed) and IPhone limitations (e.g. not being able to force the iplayer to play files with wrong extension), I have had to setup a process that reads the file in, saves it locally and then point the video player at the local file.
Although this sort of works, i am having an issue with some of the files that are large (94mb for a 17 min video) and a slow server - which takes 120 seconds to transfer the whole file.
I thought that if you started playing the video, then the transfer rate would be faster than the playback rate so the video would play ok.
However sometimes the video just crashes, which i am guessing is a result of the video reading beyond what has been written.
If the video played the internal file using progressive download I think it would probably not crash but resume once more date had been read but understand that progressive download is triggered by a url extension beginning with HTTP://
Can you make an internal file play using progressive download ? I know this would not normally be expected as logically the system would expect a local file to already be download ?
Any help appreciated
Thanks
Toby
try this to know download file is complete or not
HCDownload
it is very easy to use only write its delegate method.
Edit
also see StitchedStreamPlayer

MPMoviePlayerController & .m3u8 playlist

I would like to use a .m3u8 playlist containing remote mp4 files with MPMoviePlayerController, did you success with this ?
Does the .m3u8 must contain .ts file ?If not what is the purpose of .ts ?
Does next / previous buttons will be enable once the playlist be loaded ?
If not, what is the purpose of these buttons ?
And last question, do you have a .m3u8 sample file with remote mp4 file to test ?
Thanks a lot for your help.
Thierry
Since you're talking about .m3u8 and .ts files, can I assume you're interested in HTTP Live Streaming, as supported by iPhone OS 3.0 and Snow Leopard? There is more info about HTTP Live Streaming in the documentation.
In HTTP Live Streaming, the .m3u8 file lists other files that are to be downloaded and played in order. If the .m3u8 file doesn't contain an #EXT-X-ENDLIST directive, then the client assumes the source is a live stream, and periodically re-fetches the .m3u8 to find new media files to download. The .ts files are MPEG-2 trasnsport stream files that contain muxed audio and video (despite the fact that the transport stream is part of the MPEG-2 spec, the contents should be H.264 and AAC, the audio and video codecs usually associated with MPEG-4). You sometimes see other contents, like .aac for audio-only streams. A server will segment a video stream into many .ts files, the .m3u8 file will provide URLs for these .ts files, and a client will download and play the .ts files in order. As an iPhone developer, all you have to do is provide the .m3u8 URL to the MPMoviePlayerController, which will handle the rest.
Don't know about the prev/next buttons... don't seem like they'd make sense in a stream context, and I'm not sure whether the the MPMoviePlayerController even shows them. You can use the movieControlMode property to set what controls are offered to the user.
Apple's docs provide links to some sample test pattern streams.

Streaming "proxy" converting video formats

This is related to my another question
Here I'd like to ask if it is in theory (according to video file formats and codecs, etc) possible to have such scenario:
1) Client on iPhone has a reference to video in flv format. It sends http request to converting "proxy" like http://convproxy.com?source=url_of_original_video.flv by just clicking such link in Safari
2) Converting proxy starts downloading that flv file and converting it to mp4 (which iphone understands) on the fly, returning converted portion as http response, so iPhone can immediately start playing it, before entire flv is downloaded and converted.
I was playing with ffmpeg trying to do such thing, and it indeed converts flv and produces mp4 file, however that mp4 file can not be played until convertion is finished or ffmpeg is stopped. If I just kill ffmpeg process the mp4 file can not be played. If I let it finish or press ctrl-c to stop it, the part that was downloaded and converted can be played. Seems like ffmpeg does some job after it receives stop signal. Is that a necessary part of mp4 format or it can be done differently? I see that iPhone can stream video, by starting playing before the entire file is downloaded to it, so in general it seems like possible scenario for me.
I short words, I can convert flv file to mp4 file, and the question is if I can convert flv stream to mp4 stream.
According to wikipedia, the MP4 container format requires a separate "hint track" to enable streaming. I assume ffmpeg writes this at the end of the conversion. If the iPhone OS requires this track to stream, I don't see a way to stream live video outside of using a different format and having a custom decoder on the iPhone side similar to how the Orb client for iPhone does it.

Simultaneously stream and save a video?

I'm writing an app, part of which allows the user stream/play videos. I want to restrict the functionality so that they can only stream videos if they have a WiFi connection. I will then save the video so that when they have a 3G only (or lesser) connection they can't stream videos and can only replay videos that are saved on the phone.
Ideally, I'd like to get MPMoviePlayerController to stream/play the movie and then access the movie data and save it. However, the MPMoviePlayerController api doesn't seem to support access to the movie data.
I'd like to avoid and download-then-play scenario. Any ideas?
Two solutions come to mind.
Both this solutions require that the file is in a format that can be played progressive, e.g. that you don't need the whole file to be able to play it (but that would be a prerequisite anyway).
use a thread to download the data and append it to a file, and play the file from another thread. Now, that requires that you can handle EOF events in the MPMoviePlayerController and pause the playing until the cache file is appended to and then resume for the same point.
So far what I've seen people doing this it doesn't work because MPMoviePlayerController can't handle the EOF event. (not tested it my self yet) [Caching videos to disk after successful preload by MPMoviePlayerController
Skip the playing from a file and setup a local HTTP server and stream from that (on localhost). This is also not tested.
The idea is that MPMoviePlayerController would handlle the event of missing data better from a HTTP stream then from reading the file directly.
Downside might be that it is less efficient, but I think that is a minor increase in CPU. I don't know if the network interface would handle it, but I'm assuming it's not an issue.
I leave this answer as a wiki, because I don't have a working solution but I too want one.
There is a way to make this work, but you have to write your own HTTP Live Streaming downloader.
Basically, you parse the .m3u8 file (it's a pretty simple standard, but can get tricky with alternate streams and the possibility that the stream will simply drop out and need a new playlist to continue) and then download the chunks in .ts format to your local storage, say the Documents folder or Caches etc.
Then you'll have to set up a local HTTP server to allow the MPMoviePlayerController or AVPlayer to access the files over HTTP (since they won't touch a local file path), including a re-coded playlist file pointing to the local files, which you'll have to create yourself from the original playlist(s).
CocoaHTTPServer works great for this.
Once you've done all that, it works great. It's unavoidable that you get a little delay while you download the first chunk or two before presenting your local HTTP URL to the movie player, but after that you get seamless download, recording and preview playback.
Good luck!
the iPhone is using progressive download so it will not save on the device. For that you need to explicitly download it and then play the video from your local folder.