1

我正在更改 Aperture 代码以设置自定义视频比特率。当我录制视频时,质量和帧率都很好,但我发现元数据有问题。当我运行 ffmpeg 转换时,我看到以下错误:

DTS 96841521, next:14266523 st:0 invalid dropping
PTS 96841581, next:14266523 invalid dropping st:0

我的代码似乎生成了不正确的 PTS/DTS 值。这是我的代码:

//
//  ViewController.swift
//  CustomCamera
//
//  Created by Taras Chernyshenko on 6/27/17.
//  Copyright © 2017 Taras Chernyshenko. All rights reserved.
//
import AVFoundation
import Photos

class NewRecorder: NSObject,
  AVCaptureAudioDataOutputSampleBufferDelegate,
AVCaptureVideoDataOutputSampleBufferDelegate {

  private var session: AVCaptureSession = AVCaptureSession()
  private var deviceInput: AVCaptureScreenInput?
  private var previewLayer: AVCaptureVideoPreviewLayer?
  private var videoOutput: AVCaptureVideoDataOutput = AVCaptureVideoDataOutput()
  private var audioOutput: AVCaptureAudioDataOutput = AVCaptureAudioDataOutput()

  //private var videoDevice: AVCaptureDevice = AVCaptureScreenInput(displayID: 69731840) //AVCaptureDevice.default(for: AVMediaType.video)!
  private var audioConnection: AVCaptureConnection?
  private var videoConnection: AVCaptureConnection?

  private var assetWriter: AVAssetWriter?
  private var audioInput: AVAssetWriterInput?
  private var videoInput: AVAssetWriterInput?

  private var fileManager: FileManager = FileManager()
  private var recordingURL: URL?

  private var isCameraRecording: Bool = false
  private var isRecordingSessionStarted: Bool = false

  private var recordingQueue = DispatchQueue(label: "recording.queue")

  /*@IBAction func recordingButton(_ sender: Any) {
    if self.isCameraRecording {
      self.stopRecording()
    } else {
      self.startRecording()
    }
    self.isCameraRecording = !self.isCameraRecording
  }*/

  func setup() {
    self.session.sessionPreset = AVCaptureSession.Preset.high

    self.recordingURL = URL(fileURLWithPath: "\(NSTemporaryDirectory() as String)/file.mp4")
    if self.fileManager.isDeletableFile(atPath: self.recordingURL!.path) {
      _ = try? self.fileManager.removeItem(atPath: self.recordingURL!.path)
    }

    self.assetWriter = try? AVAssetWriter(outputURL: self.recordingURL!,
                                          fileType: AVFileType.mp4)
    self.assetWriter!.movieFragmentInterval = kCMTimeInvalid
    self.assetWriter!.shouldOptimizeForNetworkUse = true

    let audioSettings = [
      AVFormatIDKey : kAudioFormatMPEG4AAC,
      AVNumberOfChannelsKey : 2,
      AVSampleRateKey : 44100.0,
      AVEncoderBitRateKey: 192000
      ] as [String : Any]



     let videoSettings = [
      AVVideoCodecKey : "avc1",
      AVVideoWidthKey : 1920,
      AVVideoHeightKey : 1080,
      AVVideoCompressionPropertiesKey: [
       AVVideoAverageBitRateKey:  NSNumber(value: 5000000)
       ]
      ] as [String : Any]


    self.videoInput = AVAssetWriterInput(mediaType: AVMediaType.video,
                                         outputSettings: videoSettings)
    self.audioInput = AVAssetWriterInput(mediaType: AVMediaType.audio,
                                         outputSettings: audioSettings)

    self.videoInput?.expectsMediaDataInRealTime = true
    self.audioInput?.expectsMediaDataInRealTime = true

    if self.assetWriter!.canAdd(self.videoInput!) {
      self.assetWriter?.add(self.videoInput!)
    }

    if self.assetWriter!.canAdd(self.audioInput!) {
      self.assetWriter?.add(self.audioInput!)
    }

    //self.deviceInput = try? AVCaptureDeviceInput(device: self.videoDevice)
    self.deviceInput = AVCaptureScreenInput(displayID: 69731840)
    self.deviceInput!.minFrameDuration = CMTimeMake(1, Int32(30))
    self.deviceInput!.capturesCursor = true
    self.deviceInput!.capturesMouseClicks = true


    self.session.startRunning()

    DispatchQueue.main.async {
      self.session.beginConfiguration()

      if self.session.canAddInput(self.deviceInput!) {
        self.session.addInput(self.deviceInput!)
      }

      if self.session.canAddOutput(self.videoOutput) {
        self.session.addOutput(self.videoOutput)
      }

      self.videoConnection = self.videoOutput.connection(with: AVMediaType.video)
      /*if self.videoConnection?.isVideoStabilizationSupported == true {
        self.videoConnection?.preferredVideoStabilizationMode = .auto
      }*/
      self.session.commitConfiguration()

      let audioDevice = AVCaptureDevice.default(for: AVMediaType.audio)
      let audioIn = try? AVCaptureDeviceInput(device: audioDevice!)

      if self.session.canAddInput(audioIn!) {
        self.session.addInput(audioIn!)
      }

      if self.session.canAddOutput(self.audioOutput) {
        self.session.addOutput(self.audioOutput)
      }

      self.audioConnection = self.audioOutput.connection(with: AVMediaType.audio)
    }
  }

  func startRecording() {
    if self.assetWriter?.startWriting() != true {
      print("error: \(self.assetWriter?.error.debugDescription ?? "")")
    }

    self.videoOutput.setSampleBufferDelegate(self, queue: self.recordingQueue)
    self.audioOutput.setSampleBufferDelegate(self, queue: self.recordingQueue)
  }

  func stopRecording() {
    self.videoOutput.setSampleBufferDelegate(nil, queue: nil)
    self.audioOutput.setSampleBufferDelegate(nil, queue: nil)

    self.assetWriter?.finishWriting {
      print("Saved in folder \(self.recordingURL!)")
      exit(0)
    }
  }
  func captureOutput(_ captureOutput: AVCaptureOutput, didOutput
    sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

    if !self.isRecordingSessionStarted {
      let presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
      self.assetWriter?.startSession(atSourceTime: presentationTime)
      self.isRecordingSessionStarted = true
    }

    let description = CMSampleBufferGetFormatDescription(sampleBuffer)!

    if CMFormatDescriptionGetMediaType(description) == kCMMediaType_Audio {
      if self.audioInput!.isReadyForMoreMediaData {
        //print("appendSampleBuffer audio");
        self.audioInput?.append(sampleBuffer)
      }
    } else {
      if self.videoInput!.isReadyForMoreMediaData {
        //print("appendSampleBuffer video");
        if !self.videoInput!.append(sampleBuffer) {
          print("Error writing video buffer");
        }
      }
    }
  }
}

您能帮我如何更改我的代码以生成正确的 PTS/DTS 吗?谢谢

4

0 回答 0