2017-08-27 3 views
1

Ich habe versucht, ein Audio und ein Video, die von NSFileManager stammen, zusammenführen. Als ich es versuchte, bekam ich einen Fehler. Dann habe ich ein anderes Projekt erstellt und es ist völlig in Ordnung. Aber wenn ich versuche, dies in meinem Hauptprojekt auszuführen, erhalte ich einen Fehler.0 über Grenzen für leere NSArray

beenden app aufgrund nicht abgefangene Ausnahme 'NSRangeException', Grund: '*** - [__ NSArray0 objectAtIndex:]: Index 0 über Grenzen für leere NSArray'

Hier ist, wie ich versuche, zu fusionieren:

Um Daten aus dem Dokumentenverzeichnis zu erhalten, habe ich eine Funktion namens getData geschrieben.

func getData(){ 
    let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! 

    do { 
     // Get the directory contents urls (including subfolders urls) 
     let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: []) 
     print(directoryContents) 

     // if you want to filter the directory contents you can do like this: 
     videoUrlforMarge = directoryContents.filter{ $0.pathExtension == "mov" } as [AnyObject] 
     //videoUrlforMarge.append(directoryContents[1] as AnyObject) 
     print("this video \(videoUrlforMarge[0])") 

     audioUrl = directoryContents.filter{ $0.pathExtension == "caf" } as [AnyObject] 
    } catch let error as NSError { 
     print(error.localizedDescription) 
    } 
} 

Hier ist meine Merge-Funktion:

func mergeFilesWithUrl(videoUrl:NSURL, audioUrl:NSURL) 
{ 
    let mixComposition : AVMutableComposition = AVMutableComposition() 
    var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = [] 
    var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = [] 
    let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction() 

    //start merge 
    let aVideoAsset : AVAsset = AVAsset(url: videoUrl as URL) 
    let aAudioAsset : AVAsset = AVAsset(url: audioUrl as URL) 

    mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)) 
    mutableCompositionAudioTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)) 

    let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0] 
    let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaTypeAudio)[0] 

    do{ 
     try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: kCMTimeZero) 

     try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: kCMTimeZero) 
    }catch{ 
    } 

    totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,aVideoAssetTrack.timeRange.duration) 

    let mutableVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition() 
    mutableVideoComposition.frameDuration = CMTimeMake(1, 30) 

    mutableVideoComposition.renderSize = CGSize(width: 1280, height: 720) 

    //  playerItem = AVPlayerItem(asset: mixComposition) 
    //  player = AVPlayer(playerItem: playerItem!) 
    // 
    // 
    //  AVPlayerVC.player = player 

    //  let fm = FileManager.default 
    //  let docsurl = try! fm.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) 
    //  let savePathUrl = docsurl.appendingPathComponent("temp.mp4") 

    //find your video on this URl 
    //let savePathUrl : NSURL = NSURL(fileURLWithPath: NSHomeDirectory() + "/Documents/newVideo.mp4") 
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] 
    let savePathUrl = NSURL(string: ("\(documentsURL.appendingPathComponent("temp"))" + ".mp4")) 

    let VideoFilePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("mergeVideo\(arc4random()%1000)d")!.appendingPathExtension("mp4").absoluteString 

    if FileManager.default.fileExists(atPath: VideoFilePath) 
    { 
     do 
     { 
      try FileManager.default.removeItem(atPath: VideoFilePath) 
     } 
     catch { } 
    } 

    let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)! 
    assetExport.outputFileType = AVFileTypeMPEG4 
    assetExport.outputURL = NSURL(fileURLWithPath: VideoFilePath) as URL 
    assetExport.shouldOptimizeForNetworkUse = true 

    assetExport.exportAsynchronously {() -> Void in 
     switch assetExport.status { 

     case AVAssetExportSessionStatus.completed: 
      //Uncomment this if u want to store your video in asset 

      let assetsLib = ALAssetsLibrary() 
      assetsLib.writeVideoAtPath(toSavedPhotosAlbum: savePathUrl! as URL, completionBlock: nil) 

      print("success") 
     case AVAssetExportSessionStatus.failed: 
      print("failed \(String(describing: assetExport.error))") 
     case AVAssetExportSessionStatus.cancelled: 
      print("cancelled \(String(describing: assetExport.error))") 
     default: 
      print("complete") 
     } 
    } 
} 

und schließlich versuche ich, durch eine Aktion zu verschmelzen und hier ist es.

Ich folgte einige Code in Stack-Überlauf, aber habe diesen Fehler.

+0

In welcher Zeile tritt dieser Fehler auf? – 3stud1ant3

+0

in welcher Zeile stoppen Sie die Ausführung Ihrer App mit dem Absturz? –

+0

Ich habe versucht, mithilfe von Break Poin zu debuggen. Nachdem Sie diese Zeile aufgerufen haben, lassen Sie aAudioAssetTrack: AVAssetTrack = aAudioAsset.tracks (withMediaType: AVMediaTypeAudio) [0] App-Absturz. –

Antwort

1

Stellen Sie sicher, dass Ihre aVideoAsset.tracks(withMediaType: AVMediaTypeVideo) Array und aAudioAsset.tracks(withMediaType: AVMediaTypeAudio) Array einen Wert, bevor der Zugriff auf die Position durch einen Index im Array haben, können Sie eine Wache Hinzufügen helfen mit diesem

guard aVideoAsset.tracks(withMediaType: AVMediaTypeVideo).count > 0 && aAudioAsset.tracks(withMediaType: AVMediaTypeAudio) > 0 else{ 
      return 
     } 

let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0] 
let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaTypeAudio)[0] 

Auch Stellen Sie sicher, dass Ihre videoUrlforMarge Array und audioUrl Array haben einen gewissen Wert, bevor der Zugriff auf die Position in der Anordnung durch den Index, nach dem gleichen Verfahren

Ihre mergeTest Aktionscode ersetzen durch dieses

@IBAction func margeTest(_ sender: Any) { 

     guard videoUrlforMarge.count > 0 && audioUrl.count > 0 else{ 
      return 
     } 

     let videoUrl = videoUrlforMarge[0] 
     let url = NSURL(fileURLWithPath: videoUrl.absoluteString!!) 
     let audio = audioUrl[0] 
     let urla = NSURL(fileURLWithPath: audio.absoluteString!!) 

     self.mergeFilesWithUrl(videoUrl: url , audioUrl: urla) 
    } 

Meine Antwort hilft Ihnen nicht mit WARUM SIE LEER PROBLEM Arrays sind aber helfen Ihnen das nicht zum Absturz zu tun, vielleicht ist das Problem, das von Ihrem aVideoAsset und aAudioAsset Urls verursacht für die Initialisierung verwendet

aktualisiert

auf diese Weise versuchen, Ihre savePathUrl zu bekommen arbeiten

let filename = "temp.mp4" 
    let documentsURL = URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!) 
    let savePath = documents.appendingPathComponent(fileName).path 
    let savePathUrl = URL(fileURLWithPath: savePath) 
+0

es funktioniert nicht für mich. Immer noch derselbe Fehler. –

+0

@FaizulKarim erneut überprüfen Ich hatte meine Antwort erneut aktualisiert, nachdem ich wusste, welche Leitung abstürzte, bitte versuchen Sie es erneut und lassen Sie mich wissen –

+0

Thank's Reiner melian. Der Fehler ist weg. Aber mein Video speichert keine Fotos.Aber ich war sicher Videos auf diese Weise –

Verwandte Themen