DevNotes icon indicating copy to clipboard operation
DevNotes copied to clipboard

请问,我录制完视频后,把2个视频拼接在一起,加起来60秒的视频,转码要20秒,如何减少这个时间

Open wlinshicong opened this issue 7 years ago • 12 comments

AVAssetExportSession输出合成的视频太慢了

wlinshicong avatar Aug 22 '17 08:08 wlinshicong

没做过类似需求。 大致想法,边录制 边输出。 要是必须用户自己选择两个已经录制好的。可能只能降低输出参数。 其他办法你自己再找找吧~期待你找到然后回来告诉我。谢谢

Damonvvong avatar Aug 22 '17 14:08 Damonvvong

我现在用你的demo,边录制边输出。然后每一帧都用CIFilter加上了图片水印。 /** ======= 在这里可以利用 fiter 把 imageBuffer 处理后写入文件中 */ CVPixelBufferRef imageBuffer2 =[self coreImageHandle:imageBuffer1];//此处进行了水印处理 CIImage *inputImage2 = [CIImage imageWithCVPixelBuffer:imageBuffer2];//此处打断点看到图片是加了水印的了,但是录制后的视频帧数不稳定,还有就是完全看不到水印,请问怎么回事, if (self.assetWriterVideoInput.readyForMoreMediaData) {

// if (![self.assetWriterVideoInput appendSampleBuffer:sampleBuffer]) { //
// } // assetWriterInputPixelBufferAdaptor 应该是 从 imageBuffer 截取某一部分画面 然后再加入到 assetWriterVideoInput 中去 if (![self.assetWriterInputPixelBufferAdaptor appendPixelBuffer:imageBuffer2 withPresentationTime:timestamp]) {

			*error = DWVideoRecoderError(@"Failed to Appending Video Buffer",DWVideoRecoderErrorFailedToAppendVideoBuffer);

		}
	}

wlinshicong avatar Aug 23 '17 06:08 wlinshicong

  • (CVPixelBufferRef)coreImageHandle:(CVPixelBufferRef)pixelBuffer

{ CFAbsoluteTime elapsedTime, startTime = CFAbsoluteTimeGetCurrent(); CIImage *inputImage = [CIImage imageWithCVPixelBuffer:pixelBuffer]; //设置滤镜的输入图像 // [_coreImageFilter setValue:inputImage forKey:kCIInputImageKey];

CIImage *img = [CIImage imageWithCGImage:[UIImage imageNamed:@"123"].CGImage];
[_coreImageFilter setDefaults];
[_coreImageFilter setValue:inputImage forKey:@"inputBackgroundImage"];
[_coreImageFilter setValue:img forKey:@"inputImage"];

//输出的图片
CIImage *outputImage = [_coreImageFilter outputImage];
elapsedTime = CFAbsoluteTimeGetCurrent() - startTime;
NSLog(@"Core Image frame time: %f", elapsedTime * 1000.0);
[_coreImageContext render:outputImage toCVPixelBuffer:pixelBuffer];
return pixelBuffer;

} 加水印的方法

wlinshicong avatar Aug 23 '17 06:08 wlinshicong

还有你的demo如果录制视频点击几次屏幕后会崩溃报错,就是报assetWriter的状态为2,不能再重复调用self.assetWriter finishWritingWithCompletionHandler,改了这个解决了- (void)stopWritingWithError:(NSError **)error {

self.isWriting = NO;

dispatch_async(self.dispatchQueue, ^{
	if (self.assetWriter.status == AVAssetWriterStatusCompleted) {
        NSLog(@"状态已完成,不能继续完成");
        return ;
    }
	[self.assetWriter finishWritingWithCompletionHandler:^{
		
		if (self.assetWriter.status == AVAssetWriterStatusCompleted) {
			
			dispatch_async(dispatch_get_main_queue(), ^{
				if ([self.delegate respondsToSelector:@selector(videoWriter:didOutputVideoAtPath:)]) {
					[self.delegate videoWriter:self didOutputVideoAtPath:self.assetWriter.outputURL];
				}
			});
			
		} else {
			
			*error = self.assetWriter.error;
			
		}
        self.assetWriter = nil;
	}];
});

} 暂停之后self.assetWriter = nil;如果self.assetWriter.status == AVAssetWriterStatusCompleted就返回

wlinshicong avatar Aug 23 '17 06:08 wlinshicong

首先关于水印这个东西,视觉上加了水印不代表 CVPixelBufferRef 加了水印。我看了下你的实现,直觉上是错误的。按道理应该对 CVPixelBufferRef 的texture进行修改。 建议可以把水印加到layer上。参考 https://stackoverflow.com/questions/15932041/how-can-i-add-a-watermark-in-a-captured-video-on-ios。 最后通过AVFoundation的办法直接输出。 最后的bug可以帮忙提个pr么。😝

Damonvvong avatar Aug 23 '17 07:08 Damonvvong

http://www.jianshu.com/p/a20995e1ab67你看下这个,作者说这样是可以的,以前没接触过,理解不深

wlinshicong avatar Aug 23 '17 07:08 wlinshicong

不好意思,没拉过pr,不会弄,git还没装

wlinshicong avatar Aug 23 '17 07:08 wlinshicong

至于你说的哪个水印加到层上,那就是我最开始的做法。1分钟的视频要转码20秒,所以这个方案不行

wlinshicong avatar Aug 23 '17 07:08 wlinshicong

不能录制完再加水印,要等太久了,我们假如录制10分钟,不得等3分钟转码,所以必须改为边录制边加水印,

wlinshicong avatar Aug 23 '17 07:08 wlinshicong

而且你代码里的注释就写了在那个地方用filter去处理==

wlinshicong avatar Aug 23 '17 07:08 wlinshicong

恩。回头有空看看。很久之前写的了。已经记不太清了。

Damonvvong avatar Aug 23 '17 07:08 Damonvvong

我发现你的好像都没有哪个cache缓存,你也是接收到一阵帧就保存一帧,我还一直以为你是把微信调优的方法实现了,这样子的话,还是会出现丢帧的

wlinshicong avatar Aug 25 '17 10:08 wlinshicong