मैं स्थानीय एम 4 ए या एमपी 3 फ़ाइल लेने और इस फ़ाइल को संक्षिप्त/डाउन-नमूना लेने की कोशिश कर रहा हूं (एक छोटी फ़ाइल बनाने के प्रयोजनों के लिए)।AVAssetWriter डाउन-नमूना/संपीड़ित एम 4 ए/एमपी 3 फाइलें कैसे लिखें
मूल रूप से, मैं एक एवीएसेट को एक अस्थायी निर्देशिका में निर्यात करने के लिए AVAssetExportSession का उपयोग कर रहा था, लेकिन मेरे पास संपीड़न/डाउन-नमूनाकरण पर कोई नियंत्रण नहीं था (आप केवल प्रीसेट का उपयोग कर सकते हैं, उनमें से केवल, केवल .wav फ़ाइल स्वरूप समर्थन गुणवत्ता गिरावट)।
फिर, SO पर कई उदाहरणों के बाद, मैंने इस 'निर्यात' को पूर्ववत करने के लिए AVAssetReader/AVAssetWriter का उपयोग करने का प्रयास किया।
मैं जैसे मेरी रीडर/राइटर बनाएँ:
NSString *exportPath = [NSHomeDirectory() stringByAppendingPathComponent:@"out.m4a"];
NSURL *exportURL = [NSURL fileURLWithPath:outPath];
// reader
NSError *readerError = nil;
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset
error:&readerError];
AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
AVAssetReaderTrackOutput *readerOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:track
outputSettings:nil];
[reader addOutput:readerOutput];
// writer
NSError *writerError = nil;
AVAssetWriter *writer = [[AVAssetWriter alloc] initWithURL:exportURL
fileType:AVFileTypeAppleM4A
error:&writerError];
AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
// use different values to affect the downsampling/compression
NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
[NSNumber numberWithFloat:44100.0], AVSampleRateKey,
[NSNumber numberWithInt:2], AVNumberOfChannelsKey,
[NSNumber numberWithInt:128000], AVEncoderBitRateKey,
[NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey,
nil];
AVAssetWriterInput *writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio
outputSettings:outputSettings];
[writerInput setExpectsMediaDataInRealTime:NO];
[writer addInput:writerInput];
और फिर मैं लेखन शुरू ...
[writer startWriting];
[writer startSessionAtSourceTime:kCMTimeZero];
[reader startReading];
dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);
[writerInput requestMediaDataWhenReadyOnQueue:mediaInputQueue usingBlock:^{
NSLog(@"Asset Writer ready : %d", writerInput.readyForMoreMediaData);
while (writerInput.readyForMoreMediaData) {
CMSampleBufferRef nextBuffer;
if ([reader status] == AVAssetReaderStatusReading && (nextBuffer = [readerOutput copyNextSampleBuffer])) {
if (nextBuffer) {
NSLog(@"Adding buffer");
[writerInput appendSampleBuffer:nextBuffer];
}
} else {
[writerInput markAsFinished];
switch ([reader status]) {
case AVAssetReaderStatusReading:
break;
case AVAssetReaderStatusFailed:
[writer cancelWriting];
break;
case AVAssetReaderStatusCompleted:
NSLog(@"Writer completed");
[writer endSessionAtSourceTime:asset.duration];
[writer finishWriting];
NSData *data = [NSData dataWithContentsOfFile:exportPath];
NSLog(@"Data: %@", data);
break;
}
break;
}
}
}];
जब मैं लिख लेता हूँ, डेटा मैं माना जाता है कि करने के लिए लिखा है exportURL शून्य है, और लेखक एक सफल समापन की रिपोर्ट करता है। आपके हिसाब से क्या गलत हो सकता है?
अद्यतनappendSampleBuffer:
बुला के बाद लेखक स्थिति AVAssetWriterStatusFailed है, पाठकों स्थिति सफल होता है, और पूरी फ़ाइल के माध्यम से पढ़ने के लिए लगता है, हालांकि। NSString *exportPath = [NSHomeDirectory() stringByAppendingPathComponent:@"out.m4a"]
में NSHomeDirectory() का उपयोग नहीं फ़ाइल बनाने के लिए सक्षम होने के लिए लेखक पैदा कर रहा था
:
क्या यह कभी भी कुछ लिखने का प्रयास करता है? पहली बार पाठक स्थिति क्या है जब यह नमूनाबफर को जोड़ने की कोशिश करता है? – BlueVoodoo
आह हे, यह हर कदम पर दिखाई देता है जब '[writerInput appendSampleBuffer:]' कहा जाता है, लेखक की स्थिति 3 है, जो enum को देखकर, AVAssetWriterStatusFailed की तरह दिखता है। ऐसा लगता है कि पाठक मेरी संपत्ति से सभी नमूना बफर की प्रतिलिपि बना रहा है हालांकि - appendSampleBuffer को * कई * बार – Dfowj