はじめに
iOSには動画ファイルを簡単にエンコードするためのAVAssetExportSessionクラスがあります。このクラスを利用して動画をエンコードするにあたり設定する項目にshouldOptimizeForNetworkUseというものがあります。まずはドキュメントを読んでみましょう。
ムービーをネットワーク用に最適化するかどうかを示すブール値
この説明を読むと、ローカルではなくネットワーク上に配置した動画ファイルの再生に一役買ってくれそうなものだと考えられます。
考察
動画の配信方法には、大きく2つの方法「プログレッシブダウンロード」と「ストリーミング配信」があります。
プログレッシブダウンロードは、再生するクライアントに動画ファイルをまるまるダウンロードして再生する方法で、ストリーミング配信は、細切れの映像を受信し再生する方法となります。
AVAssetExportSessionでは1つの動画ファイルが出力されるため、前者のプログレッシブダウンロード用の設定となります。
プログレッシブダウンロードは、再生するために動画ファイルそのものをダウンロードする必要があり、動画ファイルのデータサイズが大きいと、再生するまでに時間がかかる欠点があります。
その欠点を補うものとして、Fast Startなるものがあります。
動画ファイルの中身は、ftyp・mdat・moovといったもので構成されており、mdatが映像や音声、moovは動画のサイズや再生時間などの情報が入っています。
プログレッシブダウンロードは、動画の先頭データから順次ダウンロードするため、moov情報が読み込めるまでは動画の再生ができません。
そのmoov情報を早めに読めるようにしようというのが、Fast Startです。
通常は、mdatの後にmoovといった順番ですが、moovの後にmdatという順番にすることで、動画情報を先に読み込み、データが読み込めたところから順次動画を再生することが可能となります。
確認
では、実際にshouldOptimizeForNetworkUse
でmdatとmoovの順番が入れ替わっているかテストしました。
mp4ファイルの解析は、こちらをお借りして、下記サンプルファイルでshouldOptimizeForNetworkUse
を書き換えてテストしてみた結果、true
のときにmoov
が先になっていることを確認できました。
guard let session = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset1280x720) else {
return
}
let outputUrl = URL(fileURLWithPath: NSTemporaryDirectory())
.appendingPathComponent(UUID().uuidString)
.appendingPathExtension("mp4")
session.shouldOptimizeForNetworkUse = true
session.outputFileType = .mp4
session.outputURL = outputUrl
session.exportAsynchronously {
switch session.status {
case .completed:
let result = MediaProcessor.fileNeedsOptimization(url: outputUrl)
NSLog("\(result ? "true" : "false")")
default:
break
}
}