20

I am streaming a video (.m3u8) by using AVPlayer

let url = URL(string: "http:myUrl.m3u8")
let player = AVPlayer(url: url!)
        
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = videoView.bounds
playerLayer.backgroundColor = UIColor.purple.cgColor
videoView.layer.addSublayer(playerLayer)
        
player.play()

I need to save the streaming video to gallery. I noticed that in the below delegate saves the caching video path.

func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
        // Do not move the asset from the download location
        UserDefaults.standard.set(location.relativePath, forKey: "assetPath")
       
    }

When I trying to get the url path from the UserDefaults by using the below code,

let path = UserDefaults.standard.value(forKey: "assetPath")

The result is :

Library/com.apple.UserManagedAssets.s9Giec/video_streaming_title_3E90DD91830B8992.movpkg

I find .movpkg folder structures at the answer for this question

the extension is '.movpkg' How can I convert the video to mp4 and save to Gallery.

Note

  • The movpkg file contains .frag files. It's acceptable if there is any answer provides a way to convert .frag files to a mp4 file.

  • I can create an AVAsset from .movpkg url so the answer for question "How to convert AVAsset to mp4 file" is maybe acceptable too.

For anyone wants to help, I created a repo here

https://github.com/trungducc/stackoverflow/tree/movpkg-to-mp4

You can try to convert .movpkg file to mp4 after download is finished. Note that downloading HLS streams is not supported in the simulator so please run the repo on real device.

Community
  • 1
  • 1
Vineesh TP
  • 7,755
  • 12
  • 66
  • 130
  • As per documentation https://developer.apple.com/documentation/avfoundation/avassetexportsession Read also SO answers here https://stackoverflow.com/questions/40354689/swift-how-to-record-video-in-mp4-format-with-uiimagepickercontroller – ares777 Apr 04 '19 at 07:47
  • 1
    @user3344236 `AVAssetExportSession` doesn't support to convert `.movpkg` file type. When you create an `AVAsset` by using `.movpkg` url, `asset.exportable` will always return `false`. https://developer.apple.com/documentation/avfoundation/avasset/1389245-exportable. These answers don't relate to this question at all. – trungduc Apr 04 '19 at 07:52
  • I think you can look into https://github.com/VideoFlint/VIExportSession – ares777 Apr 04 '19 at 08:25
  • Hello! Did you solve this issue? – Alexander Khitev Apr 15 '21 at 20:57
  • 1
    @AlexanderKhitev We cann't convert it – Vineesh TP Apr 19 '21 at 10:31

1 Answers1

1

According to https://en.wikipedia.org/wiki/HTTP_Live_Streaming, those "fragments" are MPEG-2 TS fragments. You can simply concatenate all these fragments and play the result in most video players, but it will not be a real mp4 file as you wanted. But it's worth testing, maybe the resulting ".ts" video file is good enough for your needs. But it isn't good enough (e.g., my favorite streamer works much better with mp4 files than with) MPEG-2 TS, it does make sense to convert. I usually do this in Linux, with ffmpeg:

ffmpeg -i all.ts -acodec copy -absf aac_adtstoasc -vcodec copy out.mp4

Where "all.ts" is the concatenation of all fragments (in proper order, of course, as specified in the m3u8 or often as part of the filename), and the output will go to "out.mp4". This conversion just plays with the containers and does not need to re-encode the video so it's very fast.

This answer may not be exactly what you're looking for (it's not objective-C or Swift code or anything you can run on your iPhone) but maybe it will give you a hint what to look for, or at least something you can test on your desktop.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Nadav Har'El
  • 11,785
  • 1
  • 24
  • 45
  • Thanks for your answer. I know about `.ts` files when downloading HLS but these `.frag` files are not. I tried to check and convert these files like the way I did with `.ts` files but it doesn't work. As I understand, after downloading `.ts` files, they converted them to another type of file and keep them as `.frag` files. – trungduc Apr 10 '19 at 14:17
  • 2
    Interesting. Maybe Apple switched to "fragmented mp4" - see for example https://bitmovin.com/hls-news-wwdc-2016/. According to some sources I read (I didn't look myself), you can actually concatenate (e.g.., Linux's cat) all the fragments together in the right order, and end up with a valid mp4 file. Did you try that? – Nadav Har'El Apr 11 '19 at 08:52
  • I didn't try that but sound like it really make sense :). I will try and tell you the result later. Again, thanks for your suggestion. – trungduc Apr 12 '19 at 08:16
  • Has anyone had success implementing this in Swift? – Sherwin Zadeh Dec 13 '19 at 01:37