質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

834閲覧

exportAsynchronouslyでエラー

knitbow

総合スコア11

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/08/22 21:46

##したいこと(Swift3.0)
音声と動画のマージ
参考サイト:http://qiita.com/edo_m18/items/cf3a183ad73bb711b195
###発生している問題・エラーメッセージ

error = Optional(Error Domain=AVFoundationErrorDomain Code=-11841 "Operation Stopped" UserInfo={NSLocalizedDescription=Operation Stopped, NSLocalizedFailureReason=The video could not be composed.})

###該当のソースコード

swift3.0

1 func mergeAudio(audioURL: NSURL, moviePathUrl: NSURL) -> URL { 2 3 // 手順1 4 5 // Compositionを生成 6 var mutableComposition = AVMutableComposition() 7 8 // 手順2 9 10 // AVAssetをURLから取得 11 var videoAsset = AVAsset(url: moviePathUrl as URL) 12 var audioAsset = AVAsset(url: audioURL as URL) 13 14 // アセットから動画・音声トラックをそれぞれ取得 15 var videoTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo)[0] 16 var audioTrack = audioAsset.tracks(withMediaType: AVMediaTypeAudio)[0] 17 18 // 手順3 19 // 動画合成用の`AVMutableCompositionTrack`を生成 20 var compositionVideoTrack = mutableComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid) 21 var compositionAudioTrack = mutableComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid) 22 23 // 手順4 24 do { 25 try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoTrack.timeRange.duration), of: videoTrack, at: kCMTimeZero) 26 } catch { 27 fatalError("videoTrack error") 28 } 29 30 do { 31 try compositionAudioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioTrack.timeRange.duration), of: audioTrack, at: kCMTimeZero) 32 } catch { 33 fatalError("audioTrack error") 34 } 35 36 // 手順5 37 38 var mutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction() 39 mutableVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoTrack.timeRange.duration) 40 mutableVideoCompositionInstruction.backgroundColor = UIColor.red.cgColor 41 42 var videoLayerInstruction = AVMutableVideoCompositionLayerInstruction() 43 videoLayerInstruction = AVMutableVideoCompositionLayerInstruction.init(assetTrack: compositionVideoTrack) 44 45 // 手順6 46 47 var mutableVideoComposition = AVMutableVideoComposition.init() 48 mutableVideoComposition.instructions = [mutableVideoCompositionInstruction] 49 50 // 手順7 51 52 let allAudioParams = NSMutableArray() 53 var audioMixInputParameters = AVMutableAudioMixInputParameters(track: compositionAudioTrack) 54 55 audioMixInputParameters.setVolumeRamp(fromStartVolume: 1.0, toEndVolume: 1.0, timeRange: CMTimeRangeMake(kCMTimeZero, mutableComposition.duration)) 56 allAudioParams.add(audioMixInputParameters) 57 58 // 手順8 59 60 var mutableAudioMix = AVMutableAudioMix() 61 mutableAudioMix.inputParameters = allAudioParams as! [AVAudioMixInputParameters] 62 63 // 手順9 64 65 // 動画の回転情報を取得する 66 67 var transform1 = videoTrack.preferredTransform; 68 var isVideoAssetPortrait = ( transform1.a == 0 && 69 transform1.d == 0 && 70 (transform1.b == 1.0 || transform1.b == -1.0) && 71 (transform1.c == 1.0 || transform1.c == -1.0)); 72 73 // 手順10 74 75 var naturalSize1 = CGSize() 76 if (isVideoAssetPortrait) { 77 naturalSize1 = CGSize(width: videoTrack.naturalSize.height, height: videoTrack.naturalSize.width); 78 }else { 79 naturalSize1 = videoTrack.naturalSize; 80 } 81 var renderWidth = naturalSize1.width 82 var renderHeight = naturalSize1.height 83 84 // 手順11 85 mutableVideoComposition.renderSize = CGSize(width: renderWidth, height: renderHeight); 86 mutableVideoComposition.frameDuration = CMTimeMake(1, 60); 87 88 // 手順12 89 // AVMutableCompositionを元にExporterの生成 90 var assetExportSession: AVAssetExportSession = AVAssetExportSession(asset: mutableComposition, presetName: AVAssetExportPreset1920x1080)! 91 assetExportSession.videoComposition = mutableVideoComposition; 92 assetExportSession.audioMix = mutableAudioMix; 93 // エクスポートファイルの設定 94 var composedMovieDirectory = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]; 95 var composedMoviePath = NSString(format:"%@/%@", composedMovieDirectory, "test.mp4"); 96 97 // すでに合成動画が存在していたら消す 98 var fileManager = FileManager.default; 99 if (fileManager.fileExists(atPath: composedMoviePath as String)) { 100 101 do { 102 try fileManager.removeItem(atPath: composedMoviePath as String) 103 } catch { 104 fatalError("removeItem file") 105 } 106 107 } 108 // 保存設定 109 var composedMovieUrl = NSURL(fileURLWithPath:composedMoviePath as String); 110 assetExportSession.outputFileType = AVFileTypeQuickTimeMovie; 111 assetExportSession.outputURL = composedMovieUrl as URL; 112 assetExportSession.shouldOptimizeForNetworkUse = true; 113 114 assetExportSession.exportAsynchronously(completionHandler: {() -> Void in 115 switch assetExportSession.status { 116 case .completed: 117 print("Crop Success! Url -> \(composedMovieUrl)") 118 case .failed, .cancelled: 119 print("error = \(assetExportSession.error)") 120 default: 121 print("error = \(assetExportSession.error)") 122 } 123 }) 124 125 return composedMovieUrl as URL 126 127 } 128

###試したこと
デバッグしたところ、下記でエラー発生

case .failed, .cancelled: print("error = \(assetExportSession.error)")

よろしくお願いします。。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

これは嫌なやつですね〜。AVCompositionは相当に気難しいんですよ。
ちょっとでも間違ってると動かないし、まともにエラーメッセージも出してくれないんですよね。

ひとまず、assetExportSession.videoComposition は無くても一応動くので、まずはそれをコメントアウトして動くかどうか見てみてはいかがでしょう。
あと、オーディオトラックがひとつだけの場合は audioMixも必須じゃなかった気もするので、これも一応コメントアウトしてみたら良いかもしれません(それで動いたらオーディオトラックの扱いに問題があることだけは分かります)

投稿2017/08/24 14:51

編集2017/08/24 14:52
YokemuraTakeshi

総合スコア297

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

knitbow

2017/08/24 20:24

assetExportSession.videoCompositionをコメントアウトしたら動きました!! 助かりました。2、3日ハマってました^^
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問