LoginSignup
2
0

More than 3 years have passed since last update.

AVPlayerで字幕表示する方法(字幕ファイル.vtt)&AVMutableCompositionの使い方

Last updated at Posted at 2019-07-12

はじめに

今回は Swift5で動画に字幕表示させたい ということで、調査した内容をまとめた記事になります。

  1. AVPlayerで字幕表示させる
  2. そのときに躓いたこと
  3. 修正版ソースコード

AVPlayerで字幕表示させる

今回はこちらを参考にしました。
https://stackoverflow.com/questions/39589710/how-to-add-external-vtt-subtitle-file-to-avplayerviewcontroller-in-tvos

ソースコードに対して、自分なりにコメントしていましたmm

video.swift

// 字幕と動画をまとめるパラメータ
let videoPlusSubtitles = AVMutableComposition()

// 動画情報
let localVideoAsset = AVURLAsset(url: URL(string: "https://aa/bb/test.mp4") ?? URL(string:"")!)
// 動画追加
let videoTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)

do{

  guard localVideoAsset.tracks.count > 0 else{
             // error msg
                return
            }
       //表示Rangeを決定する
            try? videoTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: localVideoAsset.duration),
                                             of: localVideoAsset.tracks(withMediaType: .video)[0],
                                             at: CMTime.zero)
}

// 字幕情報
let subtitleURL = URL(fileURLWithPath: model.data?[self.selected].subtitlePath ?? "")
            //字幕ファイル今回はvttファイル
            let subtitleAsset = AVURLAsset(url: "https://aa/bb/test.vtt")
// 字幕追加
            let subtitleTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .text, preferredTrackID: kCMPersistentTrackID_Invalid)
            do{
                guard subtitleAsset.tracks.count > 0 else{
                    //error msg
                    return
                }
//表示Rangeを決定する
                try? subtitleTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: localVideoAsset.duration),
                                                    of: subtitleAsset.tracks(withMediaType: .text)[0],
                                                    at: CMTime.zero)
            }
// playerにセットする
        let playerViewController = AVPlayerViewController()
        let player = AVPlayer(playerItem: AVPlayerItem(asset: videoPlusSubtitles))
        playerViewController?.player = player


    }

字幕を表示することに成功しました。
やったー!!

そのときに躓いたこと

しかし再生したときに、音声が流れないことに気がつきました。
なんで音声が流れないかというと、「// 動画情報」で映像トラックしかセットしていなかったからです。
それは下記のQiitaを見て、理解しました。
https://qiita.com/croquette0212/items/8912053e616e575a4d4a

大抵の動画ファイルは、映像トラックと音声トラックの2つに分裂していることを知りました。
映像トラックと音声トラックをセットするように改修しました。

完成ソースコード

下記のように修正したら、無事に音声が聞こえるようになりました

video.swift
// 字幕と動画をまとめるパラメータ
let videoPlusSubtitles = AVMutableComposition()

// 動画情報
let localVideoAsset = AVURLAsset(url: URL(string: "https://aa/bb/test.mp4") ?? URL(string:"")!)
// 動画追加
let videoTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
// 音声トラック追加(前回忘れていたのも)
let audioTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
        do{
            guard localVideoAsset.tracks(withMediaType: .video).count > 0 else {
                return
            }

            try? videoTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: localVideoAsset.duration),
                                             of: localVideoAsset.tracks(withMediaType: .video)[0],
                                             at: CMTime.zero)

            // 音声トラック追加(前回忘れていたのも)
            guard localVideoAsset.tracks(withMediaType: .audio).count > 0 else {
                return
            }
            try? audioTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: localVideoAsset.duration),
                                             of: localVideoAsset.tracks(withMediaType: .audio)[0],
                                             at: CMTime.zero)


        }

// 字幕情報
let subtitleURL = URL(fileURLWithPath: model.data?[self.selected].subtitlePath ?? "")
            //字幕ファイル今回はvttファイル
            let subtitleAsset = AVURLAsset(url: "https://aa/bb/test.vtt")
// 字幕追加
            let subtitleTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .text, preferredTrackID: kCMPersistentTrackID_Invalid)
            do{
                guard subtitleAsset.tracks.count > 0 else{
                    //error msg
                    return
                }
//表示Rangeを決定する
                try? subtitleTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: localVideoAsset.duration),
                                                    of: subtitleAsset.tracks(withMediaType: .text)[0],
                                                    at: CMTime.zero)
            }
// playerにセットする
        let playerViewController = AVPlayerViewController()
        let player = AVPlayer(playerItem: AVPlayerItem(asset: videoPlusSubtitles))
        playerViewController?.player = player


    }

映像トラックや音声トラックが複数ある場合は、気をつけてくださいね。
動画の構成に気がつかず、時間がかかってしまいました。
これが誰かの参考になれば、嬉しく思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0