如何从静止图像(png)创建固定长度的视频文件

huangapple go评论46阅读模式
英文:

How to render a video file of fixed length from a still image (png)

问题

我正在尝试从一张静态图像(png)创建一个指定长度的视频。
我的代码基于如何将UIImage导出为电影中提供的答案。

我的代码创建了一个正确长度的视频,但图像直到最后一帧才出现。我希望图像在整个视频的持续时间内都能显示。(这些视频将作为无间隙时间线中的占位符。)

我的代码如下:

- (NSURL*)exportImage:(NSImage*)image asMovieLength:(double)seconds {
    // ...(你的其余代码)
}

如何使图像从开头就显示,并持续指定的时间?

英文:

I am trying to create a video of a specified length from a still image (png).
My code is based on the answers given in How do I export UIImage as a movie

My code creates a video of the correct length, but the image does appear until the last frame. I want the immage to be shown for the full duration of the video. (These videos will be place-holders in a gapless timeline.)

My Code Is:

- (NSURL*)exportImage:(NSImage*)image asMovieLength:(double)seconds {

	NSURL *outFile;
	AppDelegate *theApp;
	NSError *error=nil;
	AVAssetWriter *videoWriter;
	NSDictionary *videoSettings;
	AVAssetWriterInput* writerInput;
	CVPixelBufferRef buffer = NULL;
	AVAssetWriterInputPixelBufferAdaptor *adaptor;
	
	theApp = (AppDelegate*)[[NSApplication sharedApplication] delegate];
	
	outFile = [theApp getFilenameForFillerFile];
	
	videoWriter = [[AVAssetWriter alloc] initWithURL:outFile fileType:AVFileTypeMPEG4 error:&error];
	NSParameterAssert(videoWriter);

	videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,
					 [NSNumber numberWithInt:880], AVVideoWidthKey,
					 [NSNumber numberWithInt:880], AVVideoHeightKey,
					 nil];
	
	writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
	
	adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
																			   sourcePixelBufferAttributes:nil];
	
	NSParameterAssert(writerInput);
	NSParameterAssert([videoWriter canAddInput:writerInput]);
	[videoWriter addInput:writerInput];
	
	// Start the writing session
	[videoWriter startWriting];
	[videoWriter startSessionAtSourceTime:kCMTimeZero];
	
	
	if(writerInput.readyForMoreMediaData)
	{
		CMTime zeroTime = CMTimeMake(0, 600);
		CMTime frameTime = CMTimeMake(seconds*600, 600);
		buffer = [self pixelBufferFromImage:image];

		[adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];

		[writerInput markAsFinished];
		
		[videoWriter finishWritingWithCompletionHandler:^{
			NSLog(@"Finished writing...checking completion status...");
			if (videoWriter.status != AVAssetWriterStatusFailed && videoWriter.status == AVAssetWriterStatusCompleted)
			{
				NSLog(@"Video writing succeeded.");
				
			} else
			{
				NSLog(@"Video writing failed: %@", videoWriter.error);
			}
			
		}];
		
		CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
		
		NSLog (@"Done");
	}
	
	return outFile;
}

How do I get the image to show from the start, and last for the specified time?

答案1

得分: 2

以下是翻译好的部分:

在您的代码中,以下更改对我有用。

CMTime zeroTime = CMTimeMake(0, 600);
CMTime frameTime = CMTimeMake((seconds * 0.5) * 600, 600);

buffer = [self pixelBufferFromImage:image];

[adaptor appendPixelBuffer:buffer withPresentationTime:zeroTime];
[adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
英文:

Following changes in your code did the trick for me.

CMTime zeroTime = CMTimeMake(0, 600);
CMTime frameTime = CMTimeMake((seconds * 0.5) * 600, 600);

buffer = [self pixelBufferFromImage:image];
        
[adaptor appendPixelBuffer:buffer withPresentationTime:zeroTime];
[adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];

huangapple
  • 本文由 发表于 2020年1月3日 21:31:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/59579498.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定