How to convert .movpkg to mp4

Vineesh TP picture Vineesh TP · Nov 1, 2017 · Viewed 8.5k times · Source

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.

Answer

Nadav Har'El picture Nadav Har'El · Apr 10, 2019

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.