ios - AVAssetWriterInput - 黑屏,长达 46 小时

标签 ios swift avfoundation avassetwriter avasset

我正在尝试获取 AVCaptureSession 并将其编码为 mp4。看起来这应该很简单,我正在尝试对单个 960x540 视频流进行编码;出于这个问题的目的,我不担心音频。

当我运行以下代码并使用 Xcode 从文档容器中抓取 out2.mp4 时,我在 quicktime 中出现黑屏,持续时间为 46 小时。至少分辨率看起来是正确的。这是 ffmpeg -i out2.mp4

的输出
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'out2.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2015-11-18 01:25:55
  Duration: 46:43:04.21, start: 168178.671667, bitrate: 0 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, smpte170m/bt709/bt709), 960x540, 1860 kb/s, 27.65 fps, 29.97 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      creation_time   : 2015-11-18 01:25:55
      handler_name    : Core Media Video

在这种情况下,为什么我不能将示例缓冲区附加到 AVAssetWriterInput

var videoInput: AVAssetWriterInput?
var assetWriter: AVAssetWriter?

override func viewDidLoad() {
    super.viewDidLoad()
    self.startStream()
    NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "swapSegment", userInfo: nil, repeats: false)
}

func swapSegment() {
    assetWriter?.finishWritingWithCompletionHandler(){
        print("File written")
    }
    videoInput = nil
}

func pathForOutput() -> String {
    let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    if let documentDirectory: NSURL = urls.first {
        let fileUrl = documentDirectory.URLByAppendingPathComponent("out1.mp4")
        return fileUrl.path!
    }
    return ""
}

func startStream() {
    assetWriter = try! AVAssetWriter(URL: NSURL(fileURLWithPath: self.pathForOutput()), fileType: AVFileTypeMPEG4)

    let videoSettings: [String: AnyObject] = [AVVideoCodecKey: AVVideoCodecH264, AVVideoWidthKey: 960, AVVideoHeightKey: 540]
    videoInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoSettings)
    videoInput!.expectsMediaDataInRealTime = true
    assetWriter?.addInput(videoInput!)
    assetWriter!.startWriting()
    assetWriter!.startSessionAtSourceTime(kCMTimeZero)

    let videoHelper = VideoHelper()
    videoHelper.delegate = self
    videoHelper.startSession()
}

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBufferRef, fromConnection connection: AVCaptureConnection!) {
    if let videoOutput = captureOutput as? AVCaptureVideoDataOutput {
        videoInput?.appendSampleBuffer(sampleBuffer)
    }
}

最佳答案

也许您的演示时间与您的 sourceTime (kCMTimeZero) 无关。您可以使用第一个缓冲区呈现时间戳作为源时间。

附注也许 46 小时大约是您的设备正常运行时间

关于ios - AVAssetWriterInput - 黑屏,长达 46 小时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33769972/

相关文章:

ios - 核心数据 MOC 保存暂停执行且保存失败(无错误或崩溃)

iphone - 在 MKMapView 中显示与在 map 应用程序中相同的兴趣点?

ios - 选择两首歌曲后如何关闭媒体选择器?

ios - 如何在预览 View 层上设置相机大小

swift - 如果预览内容文件夹中有 SwiftUI 预览的代码,为什么存档会失败?

swift - 如何仅裁剪 View 的左侧和右侧?

iOS - 混合两个音频文件

ios - 在 iOS 中接收推送消息

ios - 视频轨道后面的 AVFoundation UIImage

ios - 无视频输出和 [MC] 从公共(public)有效用户设置中读取。 Swift/iOS 11 错误