avsubtitleWriter demo解析(四):writeSubtitles上篇
来源:互联网 发布:淘宝客优惠券宣传海报 编辑:程序博客网 时间:2024/05/21 17:16
我已经预见到这部分会比较长,因此切分为上下两篇。
现在我们回到main函数调用void writeSubtitles(NSString *inputPath, NSString *outputPath, NSArray *subtitlesTextPaths)
首先从视频地址创建AVAsset,再创建对其的读取器AVAssetReader。这部分是为读取原视频信息做准备的。
NSError *error;// Setup the asset reader and writerAVAsset *asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:[inputPath stringByExpandingTildeInPath]]];AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:asset error:&error];if (error){NSLog(@"error creating asset reader. exiting: %@", error);return;}
同样地,根据输出地址创建AVAsset和对应的写入器AVAssetWriter。这部分是为写入新视频做准备的。
NSURL *outputURL = [NSURL fileURLWithPath:[outputPath stringByExpandingTildeInPath]];AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:outputURL fileType:AVFileTypeQuickTimeMovie error:&error];if (error){NSLog(@"error creating asset writer. exiting: %@", error);return;}
接着,拷贝原视频的metaData给写入器
// Copy metadata from the asset to the asset writerNSMutableArray *assetMetadata = [NSMutableArray array];for (NSString *metadataFormat in asset.availableMetadataFormats)[assetMetadata addObjectsFromArray:[asset metadataForFormat:metadataFormat]];assetWriter.metadata = assetMetadata;assetWriter.shouldOptimizeForNetworkUse = YES;
这边的思路是枚举asset的metadataFormats,这里返回NSString,再根据这个NSString获取AVMetadataItem。
接着将原视频里的track读出作为写入的源。
// Build up inputs and outputs for the reader and writer to carry over the tracks from the input movie into the new movieNSMutableDictionary *assetWriterInputsCorrespondingToOriginalTrackIDs = [NSMutableDictionary dictionary];NSMutableArray *inputsOutputs = [NSMutableArray array];for (AVAssetTrack *track in asset.tracks){NSString *mediaType = track.mediaType;// Make the readerAVAssetReaderTrackOutput *trackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:nil];[assetReader addOutput:trackOutput];// Make the writer input, using a source format hint if a format description is availableAVAssetWriterInput *input;CMFormatDescriptionRef formatDescription = CFBridgingRetain([track.formatDescriptions firstObject]);if (formatDescription){input = [AVAssetWriterInput assetWriterInputWithMediaType:mediaType outputSettings:nil sourceFormatHint:formatDescription];CFRelease(formatDescription);}else{NSLog(@"skipping track on the assumption that there is no media data to carry over");continue;}// Carry over language codeinput.languageCode = track.languageCode;input.extendedLanguageTag = track.extendedLanguageTag;// Copy metadata from the asset track to the asset writer inputNSMutableArray *trackMetadata = [NSMutableArray array];for (NSString *metadataFormat in track.availableMetadataFormats)[trackMetadata addObjectsFromArray:[track metadataForFormat:metadataFormat]];input.metadata = trackMetadata;// Add the input, if that's okay to doif ([assetWriter canAddInput:input]){[assetWriter addInput:input];// Store the input and output to be used later when actually writing out the new movie[inputsOutputs addObject:@{@"input" : input, @"output" : trackOutput}];// Track inputs corresponsing to track IDs for later preservation of track groupsassetWriterInputsCorrespondingToOriginalTrackIDs[@(track.trackID)] = input;}else{NSLog(@"skipping input because it cannot be added to the asset writer");}}
读取很简单,只要将track传给AVAssetReaderTrackOutput就行,这个便利构造器,产生一个AVAssetReaderTrackOutput。
写入有点麻烦,要将track的MediaType,sourceFormatHint也就是track的格式描述传给AVAssetWriterInput。这里我们只是构造了一下,还没add给写入器,因为我们的准备工作还没做完。
// Carry over language codeinput.languageCode = track.languageCode;input.extendedLanguageTag = track.extendedLanguageTag;拷贝language code和extendedLanguageTag
// Copy metadata from the asset track to the asset writer inputNSMutableArray *trackMetadata = [NSMutableArray array];for (NSString *metadataFormat in track.availableMetadataFormats)[trackMetadata addObjectsFromArray:[track metadataForFormat:metadataFormat]];input.metadata = trackMetadata;
还要拷贝track的metaData
可以将input add到写入器了
// Add the input, if that's okay to doif ([assetWriter canAddInput:input]){[assetWriter addInput:input];// Store the input and output to be used later when actually writing out the new movie[inputsOutputs addObject:@{@"input" : input, @"output" : trackOutput}];// Track inputs corresponsing to track IDs for later preservation of track groupsassetWriterInputsCorrespondingToOriginalTrackIDs[@(track.trackID)] = input;}else{NSLog(@"skipping input because it cannot be added to the asset writer");}
接着为字幕构造input
// Setup the inputs and outputs for new subtitle tracksNSMutableArray *newSubtitlesInputs = [NSMutableArray array];NSMutableArray *subtitlesInputsOutputs = [NSMutableArray array];for (NSString *subtitlesPath in subtitlesTextPaths){// Read the contents of the subtitles fileNSString *text = [NSString stringWithContentsOfURL:[NSURL fileURLWithPath:subtitlesPath] encoding:NSUTF8StringEncoding error:&error];if (!text){NSLog(@"there was a problem reading a subtitles file: %@", error);continue;}// Make the subtitles readerSubtitlesTextReader *subtitlesTextReader = [SubtitlesTextReader subtitlesTextReaderWithText:text];// Make the writer input, using a source format hint if a format description is availableAVAssetWriterInput *subtitlesInput;CMFormatDescriptionRef formatDescription = [subtitlesTextReader copyFormatDescription];if (formatDescription){subtitlesInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeSubtitle outputSettings:nil sourceFormatHint:formatDescription];CFRelease(formatDescription);}else{NSLog(@"skipping subtitles reader on the assumption that there is no media data to carry over");continue;}subtitlesInput.languageCode = subtitlesTextReader.languageCode;subtitlesInput.extendedLanguageTag = subtitlesTextReader.extendedLanguageTag;subtitlesInput.metadata = subtitlesTextReader.metadata;if ([assetWriter canAddInput:subtitlesInput]){[assetWriter addInput:subtitlesInput];// Store the input and output to be used later when actually writing out the new movie[subtitlesInputsOutputs addObject:@{@"input" : subtitlesInput, @"output" : subtitlesTextReader}];[newSubtitlesInputs addObject:subtitlesInput];}else{NSLog(@"skipping subtitles input because it cannot be added to the asset writer");}}
上篇先到这儿,有些内容以后补充。
0 0
- avsubtitleWriter demo解析(四):writeSubtitles上篇
- avsubtitleWriter demo解析(四):writeSubtitles下篇
- avsubtitleWriter demo解析(三):SubtitlesTextReader
- avsubtitleWriter demo解析(一):字幕解析
- avsubtitleWriter demo解析(二):创建CMSampleBufferRef
- 接上上篇目的demo
- 解析动态联编(上篇)
- 解析动态联编(上篇)
- Dom4j解析xml文件---上篇
- 解析动态联编(上篇)
- JavaScriptCore全面解析 (上篇)
- Android解析自定义xml文件--Dom解析xml文件,测试demo(方案四)
- 大猫品Android[四][跑通Broadcast流程-上篇]
- JAVA四种引用方式-上篇
- ndroid Fragment 真正的完全解析上篇
- kafka源码解析之十二KafkaController(上篇)
- Flask系列----快速入门实战解析(上篇)
- 深入浅出如何解析xml文件---上篇
- BlockingQueue 阻塞队列 -- Java 多线程
- mysql send packet larger错误
- THINKING IN java(实例练习)
- 有驾照不等于会开车,教你开车技巧27招
- 常用的DOS命令集合
- avsubtitleWriter demo解析(四):writeSubtitles上篇
- Git使用的简单总结
- Hello World!
- -bash: warning: setlocale: LC_CTYPE: cannot change locale (EN_US.UTF-8)
- Lucene中Filter的性能问题
- eclipse安装ADT插件
- 【黑马程序员】C#笔记之ref和out的区别
- 微软2014实习生及秋令营技术类职位在线测试——String reorder
- c++-new与delete运算符