#swift #objective-c #webrtc
#swift #objective-c #webrtc
Вопрос:
Прежде всего, извините, я не знаком с английским языком.
Я пытаюсь записать удаленное видео на webrtc.
Однако тип буфера из удаленного фрейма — RTCI420buffer .
Я нашел способ преобразовать rtci420buffer в cmsamplebuffer с помощью поиска в Google.
Буфер добавляется avassetwriter, но выводится только черный экран.
Что-то не так с тем, как я пытался?
Это конвертер, который я использовал. https://gist.github.com/shalyf/69880f70ca9470a1e91440196cb7d127
Это код, который преобразуется в CVPixelBuffer
func buffer(from image: CIImage) -> CVPixelBuffer? {
let attrs = [kCVPixelBufferMetalCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
var pixelBuffer : CVPixelBuffer?
let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(image.extent.width), Int(image.extent.height), kCVPixelFormatType_32BGRA, attrs, amp;pixelBuffer)
guard (status == kCVReturnSuccess) else {
return nil
}
return pixelBuffer
}
И это мой код для создания cmsamplebuffer
let pixelBuffer = buffer(from: CIImage(image: Converter.convert(frame))!)
let presentTime = CMTime.init(value: frame.timeStampNs, timescale: CMTimeScale(powf(10.0, 9.0)))
var sampleBuffer: CMSampleBuffer? = nil
var timimgInfo: CMSampleTimingInfo = CMSampleTimingInfo.init(duration: CMTime.indefinite, presentationTimeStamp: presentTime, decodeTimeStamp: CMTime.indefinite)
var videoInfo: CMVideoFormatDescription? = nil
CMVideoFormatDescriptionCreateForImageBuffer(allocator: nil,
imageBuffer: pixelBuffer!,
formatDescriptionOut: amp;videoInfo)
CMSampleBufferCreateForImageBuffer(allocator: kCFAllocatorDefault,
imageBuffer: pixelBuffer!,
dataReady: true,
makeDataReadyCallback: nil,
refcon: nil,
formatDescription: videoInfo!,
sampleTiming: amp;timimgInfo,
sampleBufferOut: amp;sampleBuffer)
И это мои локальные настройки AVAssetWriter
self.assetWriter!.movieFragmentInterval = CMTimeMakeWithSeconds(1.0, preferredTimescale: 1000)
var localSettings:[String:AnyObject] = Dictionary.init()
localSettings[AVVideoWidthKey] = NSNumber.init(value: Float(videoSize.width))
localSettings[AVVideoHeightKey] = NSNumber.init(value: Float(videoSize.height))
localSettings[AVVideoCodecKey] = AVVideoCodecType.h264 as NSString
self.videoWriteInput = AVAssetWriterInput(mediaType:AVMediaType.video, outputSettings:localSettings)
Это CMSampleBuffer
Optional(CMSampleBuffer 0x115d928e0 retainCount: 9 allocator: 0x1f3225860
invalid = NO
dataReady = YES
makeDataReadyCallback = 0x0
makeDataReadyRefcon = 0x0
formatDescription = <CMVideoFormatDescription 0x280c6c420 [0x1f3225860]> {
mediaType:'vide'
mediaSubType:'BGRA'
mediaSpecific: {
codecType: 'BGRA' dimensions: 1280 x 720
}
extensions: {{
CVBytesPerRow = 5120;
Version = 2;
}}
}
sbufToTrackReadiness = 0x0
numSamples = 1
outputPTS = {60493883000000/1000000000 = 60493.883}(based on cachedOutputPresentationTimeStamp)
sampleTimingArray[1] = {
{PTS = {60493883000000/1000000000 = 60493.883}, DTS = {INDEFINITE}, duration = {INDEFINITE}},
}
imageBuffer = 0x28339d540
)
Комментарии:
1. Ваш вопрос понятен. Но TBH это слишком много для распаковки. Слишком много мест, чтобы скрыть ошибку. Не могли бы вы попробовать разделить каждую часть как подпрограмму и попробовать протестировать ее отдельно? Например. сделайте неподвижное изображение и убедитесь, что ваш AVAssetWriter работает. Затем создайте все еще предопределенное изображение CIImage и убедитесь, что преобразование в CMSampleBuffer работает и т. Д. Побочное замечание заключается в том, что вы хотите получить файл H264, но вместо того, чтобы записывать его из wire, вы позволяете WebRTC сначала его декодировать, затем выполняете кучу преобразований и снова кодируете. Для меня это пустая трата процессора…