ios - 从视频文件中删除音频

标签 ios swift audio video avfoundation

我正在尝试从手机库中的 MOV 类型视频中删除音轨。我知道我可以在播放时将音频静音,但我打算上传用户视频,删除音频并减小文件大小才有意义。

我试过从 THIS ANSWER 转换 obj-c 代码 到 swift,但我要么搞砸了转换,要么只是没有从文件中取出音频。

如有任何帮助,我们将不胜感激。

最佳答案

投票最高的答案对我不起作用 + 我在视频旋转方面遇到了问题。我最终通过添加参数 muteSound: Bool 修改了我的视频压缩方法。

我使用 2300000 的比特率来保持视频看起来不错,但尺寸比原始视频小 3-4 倍。

我会保持问题开放并将投票最多的问题标记为正确。也许有人可以想出更简单的办法。

func compressVideo(inputURL: NSURL, outputURL: NSURL, bitRate: Int, muteSound: Bool, onDone: () -> ()) {
  let videoAsset = AVURLAsset(URL: inputURL, options: nil)
  let videoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
  let videoSize = videoTrack.naturalSize
  let videoWriterCompressionSettings = [
    AVVideoAverageBitRateKey: bitRate
  ]

  let videoWriterSettings:[String : AnyObject] = [
    AVVideoCodecKey : AVVideoCodecH264,
    AVVideoCompressionPropertiesKey : videoWriterCompressionSettings,
    AVVideoWidthKey : Int(videoSize.width),
    AVVideoHeightKey : Int(videoSize.height)
  ]

  let videoWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoWriterSettings)
  videoWriterInput.expectsMediaDataInRealTime = true
  videoWriterInput.transform = videoTrack.preferredTransform
  let videoWriter = try! AVAssetWriter(URL: outputURL, fileType: AVFileTypeQuickTimeMovie)
  videoWriter.addInput(videoWriterInput)

  let videoReaderSettings:[String : AnyObject] = [
    kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)
  ]

  let videoReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings)
  let videoReader = try! AVAssetReader(asset: videoAsset)
  videoReader.addOutput(videoReaderOutput)

  let audioWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: nil)
  audioWriterInput.expectsMediaDataInRealTime = false
  videoWriter.addInput(audioWriterInput)

  let audioTrack = videoAsset.tracksWithMediaType(AVMediaTypeAudio)[0]
  let audioReaderOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil)
  let audioReader = try! AVAssetReader(asset: videoAsset)
  if muteSound == false {
    audioReader.addOutput(audioReaderOutput)
  }
  videoWriter.startWriting()

  videoReader.startReading()
  videoWriter.startSessionAtSourceTime(kCMTimeZero)
  let processingQueue = dispatch_queue_create("processingQueue1", nil)
  videoWriterInput.requestMediaDataWhenReadyOnQueue(processingQueue, usingBlock: {() -> Void in
    while videoWriterInput.readyForMoreMediaData {
      let sampleBuffer:CMSampleBuffer? = videoReaderOutput.copyNextSampleBuffer()
      if videoReader.status == .Reading && sampleBuffer != nil {
        videoWriterInput.appendSampleBuffer(sampleBuffer!)
      } else {
        videoWriterInput.markAsFinished()
        if videoReader.status == .Completed {
          if muteSound {
            // return without sound
            videoWriter.finishWritingWithCompletionHandler({() -> Void in
              onDone()
            })
          } else {
            audioReader.startReading()
            videoWriter.startSessionAtSourceTime(kCMTimeZero)
            let processingQueue = dispatch_queue_create("processingQueue2", nil)

            audioWriterInput.requestMediaDataWhenReadyOnQueue(processingQueue, usingBlock: {() -> Void in
              while audioWriterInput.readyForMoreMediaData {
                let sampleBuffer:CMSampleBufferRef? = audioReaderOutput.copyNextSampleBuffer()
                if audioReader.status == .Reading && sampleBuffer != nil {
                  audioWriterInput.appendSampleBuffer(sampleBuffer!)
                } else {
                  audioWriterInput.markAsFinished()
                  if audioReader.status == .Completed {
                    videoWriter.finishWritingWithCompletionHandler({() -> Void in
                      onDone()
                    })
                  }
                }
              }
            })
          }
        }
      }
    }
  })
}

关于ios - 从视频文件中删除音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40194128/

相关文章:

Android 文件选择器将音频文件重定向到/外部

ios - 如何向下转换 UIViewController Swift

ios - SpriteKit 在暂停后不会恢复

ios - JSONModel NSString 问题

应用程序打开时的 iOS 应用程序通知(如 whatsapp)

swift - 试图了解 URLSession 身份验证挑战

swift - 使用@IBInspectable Swift 4.2 的 UIView 上的 CornerRadius 和 Shadow

python - 如何在python中播放wav文件?

windows - 如何使用虚拟音频设备驱动程序在 RDP session 中将音频从服务器重定向到客户端?

ios - 如何只让 YouTube 视频的音频运行?