動画関連の処理を行っていると以下の様なエラーが出るときがある。
Error Domain=AVFoundationErrorDomain Code=-11841 "Operation Stopped" UserInfo=0x9676a40 {NSLocalizedDescription=Operation Stopped, NSLocalizedFailureReason=The video could not be composed.}
大抵の場合、これは設定の何処かに間違いがあることが原因だ。

今回はこのエラーを追ってみよう。
 

timeRangeの設定が正しくない
前回の記事([iOS] 動画を加工・編集する(1) 指定した時間の範囲を切り出す)のソースコードで見てみよう。
この部分だ。

    // 7
    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    instruction.timeRange = inputRange;
3行目のinstruction.timeRangeに不正な値を代入したり、そもそもこの値を設定し忘れたりすると件のエラーが出る。

忘れないように注意したい。

AVMutableVideoCompositionLayerInstructionインスタンスの作成でミスする
こちらはより深刻なパターンだ。
なぜならとても気づきにくいからだ。

まずはどういう風にミスしたらダメかを見ておこう。
おさらいとして、まず正しい場合だ。

    // 8
    AVMutableVideoCompositionLayerInstruction *layerInstruction = 
[AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack];
次が間違っている場合だ。
    // 8
    AVMutableVideoCompositionLayerInstruction *layerInstruction = 
[AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
違いがわかるだろうか。
3行目で渡している引数に注目してほしい。
正しい場合はcompositionVideoTrackとなっているが、間違っている場合はvideoTrackを渡している。


では実際に間違っている場合にコードを変更して動作確認してみよう。

いかがだろうか。
正常に処理は完了したことだろうと思う。
そう、これだけなら特に問題なく処理が終了してしまうのが、この問題のやっかいなところだ。

核心に迫ろう。
今出力した動画ファイルを元動画として、再度処理を行ってみよう。

    // 1
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *inputPath = [[path stringByAppendingPathComponent:@"result"] stringByAppendingPathExtension:@"mov"];
    NSString *outputPath = [[path stringByAppendingPathComponent:@"result2"] stringByAppendingPathExtension:@"mov"];
    Float64 startTime = 0;
    Float64 duration = 1;
元動画をresult.mov、出力する動画をresult2.mov、開始を0秒、デュレーションを1秒とする。
この設定で動作確認してみよう。

件のエラーが出たはずだ!

どういうことかというと
一度は出力することが出来るが、その出力した動画をソースにして同じ処理を行おうとするとエラーとなる

ということだ。
もちろん、正しいコードの場合はこんな現象は起こらない。

なぜこのような現象が起こるのかはわからないが、一度目の出力の際に何か必要な情報が欠けてしまうのではないかと想像する。

一度出力した動画は二度と加工しないようなアプリだと気づきにくい問題だが、水面下でこの問題が起こらないようにしっかりとコードを書くようにしたい。

関連記事
[iOS] 動画を加工・編集する(1) 指定した時間の範囲を切り出す

[iOS] 動画を加工・編集する(3) 動画に音を合成する
[iOS] 動画を加工・編集する(4) 動画をクリッピングする
[iOS] 動画を加工・編集する(5) 動画を拡大縮小する
[iOS] 動画を加工・編集する(6) 複数の動画を連結する