2012-10-24 14 views
8

मैं स्थानीय एम 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() का उपयोग नहीं फ़ाइल बनाने के लिए सक्षम होने के लिए लेखक पैदा कर रहा था

:

+0

क्या यह कभी भी कुछ लिखने का प्रयास करता है? पहली बार पाठक स्थिति क्या है जब यह नमूनाबफर को जोड़ने की कोशिश करता है? – BlueVoodoo

+0

आह हे, यह हर कदम पर दिखाई देता है जब '[writerInput appendSampleBuffer:]' कहा जाता है, लेखक की स्थिति 3 है, जो enum को देखकर, AVAssetWriterStatusFailed की तरह दिखता है। ऐसा लगता है कि पाठक मेरी संपत्ति से सभी नमूना बफर की प्रतिलिपि बना रहा है हालांकि - appendSampleBuffer को * कई * बार – Dfowj

उत्तर

5

मैं समाधान बारे में जाना। बिल्कुल सही नहीं है, या मुझे इसे काम करने की अनुमति देने के लिए क्या करना होगा, लेकिन NSHomeDirectiory() से NSTemporaryDirectory() को बदलकर इस दौरान मेरी समस्याएं हल हो गई हैं।

+1

कहा जाता है आप आईओएस में होम निर्देशिका में नहीं लिख सकते हैं। अस्थायी निर्देशिका ठीक है, साथ ही साथ दस्तावेज़ निर्देशिका –

संबंधित मुद्दे