Add a subtitle with AVMutableComposition

I am trying to use AVMutableComposition on iOS 9 to combine an MP4 video with additional subtitles in WebVTT, but it does not work.


import Foundation
import AVKit
import AVFoundation
func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}
class PlayerViewController : UIViewController {
    override func viewDidAppear(animated: Bool) {
       
        let videoAsset = AVURLAsset(URL: NSURL(fileURLWithPath: "/Users/mxey/Documents/Putview/SubtitleSandbox/video.mp4"), options: [:])
        let subtitleAsset = AVURLAsset(URL: NSURL(fileURLWithPath: "/Users/mxey/Documents/Putview/SubtitleSandbox/subtitles.webvtt"), options: [:])
       
        let composition = AVMutableComposition()
       
        try! composition.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), ofAsset: videoAsset, atTime: kCMTimeZero)
        let subtitleTrack = composition.addMutableTrackWithMediaType(AVMediaTypeSubtitle, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
        try! subtitleTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, subtitleAsset.duration), ofTrack: subtitleAsset.tracks[0], atTime: kCMTimeZero)
        let playerVC = AVPlayerViewController()
        presentViewController(playerVC, animated: false, completion: nil)
        playerVC.player = AVPlayer(playerItem: AVPlayerItem(asset: composition))
        playerVC.player!.play()
       
        delay(5) {
            let item = playerVC.player!.currentItem!
            print(item.error)
        }
    }
}


The AVPlayer shows the strikethrough play button to indicate an error. The output of the print statement is:


Optional(Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSUnderlyingError=0x7f8b2bc67500 {Error Domain=NSOSStatusErrorDomain Code=-12844 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-12844), NSLocalizedDescription=The operation could not be completed})


If I use AVMediaTypeText instead of AVMediaTypeSubtitle, the video plays, but the subtitles are always visible and cannot be controlled with the usual subtitle selection menu of AVPlayer.

Replies

Hey mxey,


By any chance would you know how this would work if you were to use remote VTT files instead of local. i.e.: NSURL(string: "http://remote.vtt")?


I tried it, but there is a preload issue that prevents remote VTT from loading anything after 4:19 mins.


Thanks

It is not possible to use AVMutableComposition to establish media selection groups for the subtitles, so you can't perform this sort of client side binding.


Please submit a feature request at bugreporter.apple.com describing your use case and workflow. Thanks!

Hi mxey, did you figure a way out?

Hi,


I managed to make it work using this approach: https://stackoverflow.com/a/37945178/2328732


It also works with remote video and subtitle URLs.

Hi,

can you please share sample code. I am trying to get this work with remote URL but it is not working.