2015-08-07 5 views
2
func extractAudioFromVideo(videoUrl:NSURL, audioPath:String){ 
    //2 
    var asset = AVURLAsset(URL: videoUrl, options: nil) 
    asset.loadValuesAsynchronouslyForKeys(NSArray(object: "tracks") as [AnyObject], completionHandler: {() -> Void in 
     var audioTrack = asset.tracksWithMediaType(AVMediaTypeAudio)[0] as! AVAssetTrack 

     var audioComposition = AVMutableComposition() 

     var audioCompositionTrack:AVMutableCompositionTrack! 

     audioCompositionTrack = audioComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID()) 
     audioCompositionTrack.insertTimeRange(audioTrack.timeRange, ofTrack: audioTrack, atTime: CMTimeMake(0, 1), error: nil) 

     var exportSession = AVAssetExportSession(asset: audioComposition, presetName: AVAssetExportPresetAppleM4A) 
     var toFileUrl = NSURL(fileURLWithPath: audioPath) 

     exportSession.outputURL = toFileUrl 
     exportSession.outputFileType = "com.apple.m4a-audio" 

     exportSession.exportAsynchronouslyWithCompletionHandler({() -> Void in 
      if exportSession.status == AVAssetExportSessionStatus.Completed { 
       println("Succes") 
      }else{ 
       println("not working") 
      } 
     }) 

    }) 

} 

Я использую выше код, чтобы получить аудио из видео, но печать «не работает»Извлечение аудио из видео AVFoundation

мой аудиотракта является:

var outStr = NSBundle.mainBundle().pathForResource("cheeseburger", ofType: "m4a")

Пожалуйста, помогите мне с этим

Благодарности

ответ

1

Из моего проекта

extension AVAsset {  

    func writeAudioTrackToURL(URL: NSURL, completion: (Bool, NSError?) ->()) { 

     do { 

      let audioAsset = try self.audioAsset() 
      audioAsset.writeToURL(URL, completion: completion) 

     } catch (let error as NSError){ 

      completion(false, error) 

     } catch { 

      print("\(self.dynamicType) \(__FUNCTION__) [\(__LINE__)], error:\(error)") 
     } 
    } 

    func writeToURL(URL: NSURL, completion: (Bool, NSError?) ->()) { 

     guard let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetAppleM4A) else { 
      completion(false, nil) 
      return 
     } 

     exportSession.outputFileType = AVFileTypeAppleM4A 
     exportSession.outputURL  = URL 

     exportSession.exportAsynchronouslyWithCompletionHandler { 
      switch exportSession.status { 
      case .Completed: 
       completion(true, nil) 
      case .Unknown, .Waiting, .Exporting, .Failed, .Cancelled: 
       completion(false, nil) 
      } 
     } 
    } 

    func audioAsset() throws -> AVAsset { 

     let composition = AVMutableComposition() 

     let audioTracks = tracksWithMediaType(AVMediaTypeAudio) 

     for track in audioTracks { 

      let compositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid) 
      do { 
       try compositionTrack.insertTimeRange(track.timeRange, ofTrack: track, atTime: track.timeRange.start) 
      } catch { 
       throw error 
      } 
      compositionTrack.preferredTransform = track.preferredTransform 
     } 
     return composition 
    } 
} 

Используйте как этот

let url = NSBundle.mainBundle().URLForResource("video", withExtension: "m4v")! 
let asset = AVURLAsset(URL: url, options: nil) 

asset.writeAudioTrackToURL(NSURL(fileURLWithPath: pathTo)) { (success, error) ->() in 
    if !success { 
     print(error) 
    } 
} 
4

Я переписан ответ на Swift 4.0, поскольку некоторые изменения API сломал предыдущий.

import AVFoundation 

extension AVAsset { 
    // Provide a URL for where you wish to write 
    // the audio file if successful 
    func writeAudioTrack(to url: URL, 
         success: @escaping() ->(), 
         failure: @escaping (Error) ->()) { 
     do { 
      let asset = try audioAsset() 
      asset.write(to: url, success: success, failure: failure) 
     } catch { 
      failure(error) 
     } 
    } 

    private func write(to url: URL, 
         success: @escaping() ->(), 
         failure: @escaping (Error) ->()) { 
     // Create an export session that will output an 
     // audio track (M4A file) 
     guard let exportSession = AVAssetExportSession(asset: self, 
                 presetName: AVAssetExportPresetAppleM4A) else { 
                 // This is just a generic error 
                 let error = NSError(domain: "domain", 
                      code: 0, 
                      userInfo: nil) 
                 failure(error) 

                 return 
     } 

     exportSession.outputFileType = .m4a 
     exportSession.outputURL = url 

     exportSession.exportAsynchronously { 
      switch exportSession.status { 
      case .completed: 
       success() 
      case .unknown, .waiting, .exporting, .failed, .cancelled: 
       let error = NSError(domain: "domain", code: 0, userInfo: nil) 
       failure(error) 
      } 
     } 
    } 

    private func audioAsset() throws -> AVAsset { 
     // Create a new container to hold the audio track 
     let composition = AVMutableComposition() 
     // Create an array of audio tracks in the given asset 
     // Typically, there is only one 
     let audioTracks = tracks(withMediaType: .audio) 

     // Iterate through the audio tracks while 
     // Adding them to a new AVAsset 
     for track in audioTracks { 
      let compositionTrack = composition.addMutableTrack(withMediaType: .audio, 
                   preferredTrackID: kCMPersistentTrackID_Invalid) 
      do { 
       // Add the current audio track at the beginning of 
       // the asset for the duration of the source AVAsset 
       try compositionTrack?.insertTimeRange(track.timeRange, 
                 of: track, 
                 at: track.timeRange.start) 
      } catch { 
       throw error 
      } 
     } 

     return composition 
    } 

Затем вы вызываете расширение и полагаетесь на различные блокировки для обработки успехов и сбоев. Обработка ошибок в этом примере чрезвычайно примитивна, поэтому вы захотите улучшить ее при ее реализации.

asset.writeAudioTrack(to: url, success: { 
    print("Success") 
}) { (error) in 
    print(error.localizedDescription) 
} 
+0

Не работает для меня, получает сообщение об ошибке –

+0

@MaksimKniazev Что сказать ошибка? – CodeBender

+0

Операция не может быть завершена. (доменная ошибка 0.), однако, он делает это только для некоторых файлов, иначе он работает. –

Смежные вопросы