2016-12-24 5 views
4

.m4aオーディオファイルを取り消して書き出す方法はありますか?私はオーディオトラックを逆にする解決策を見つけましたhereしかし、それは唯一の.cafファイル形式で動作しているようです。唯一の方法が.cafを使用する場合、.m4aファイルを最初に.cafに変換する方法はありますか?オーディオファイルを取り消すSwift/Objective-C

アップデート:私はAVAssetReaderは、オーディオファイルからオーディオサンプルを読み取るために使用することができますが、私はどのように戻って逆の順序でサンプルを書くには考えていることが判明another post 。以下のコードスニペットは、投稿からの直接の回答です。どんな助けもありがとう。おかげで

+ (void) reverseAudioTrack: (AVAsset *)audioAsset outputURL: (NSURL *)outputURL { 
NSError *error; 

AVAssetReader* reader = [[AVAssetReader alloc] initWithAsset:audioAsset error:&error]; 
if (error) {NSLog(@"%@", error.localizedDescription);} 

AVAssetTrack* track = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 

NSMutableDictionary* audioReadSettings = [NSMutableDictionary dictionary]; 
[audioReadSettings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] 
        forKey:AVFormatIDKey]; 

AVAssetReaderTrackOutput* readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:audioReadSettings]; 
[reader addOutput:readerOutput]; 
[reader startReading]; 

CMSampleBufferRef sample; //= [readerOutput copyNextSampleBuffer]; 
NSMutableArray *samples = [[NSMutableArray alloc] init]; 

// Get all samples 
while((sample = [readerOutput copyNextSampleBuffer])) { 
    [samples addObject:(__bridge id)sample]; 
    CFRelease(sample); 
} 

// Process samples in reverse 
AudioChannelLayout acl; 
bzero(&acl, sizeof(acl)); 
acl.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; 

AVAssetWriter *writer = [[AVAssetWriter alloc] initWithURL:outputURL 
                fileType:AVFileTypeAppleM4A 
                 error:&error]; 
if (error) {NSLog(@"%@", error.localizedDescription);} 
NSDictionary *writerOutputSettings = [ NSDictionary dictionaryWithObjectsAndKeys: 
             [ NSNumber numberWithInt: kAudioFormatAppleLossless ], AVFormatIDKey, 
             [ NSNumber numberWithInt: 16 ], AVEncoderBitDepthHintKey, 
             [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey, 
             [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey, 
             [ NSData dataWithBytes: &acl length: sizeof(acl) ], AVChannelLayoutKey, nil ]; 

AVAssetWriterInput *audioWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:writerOutputSettings]; 

[writer addInput:audioWriterInput]; 
[writer startWriting]; 
[writer startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp((__bridge CMSampleBufferRef)samples[0]) ]; 

// (1) Would it work if I loop in reverse here? 
for (NSInteger i = 0; i < samples.count; i++) { 
    CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer((__bridge CMSampleBufferRef)samples[i]); 

    CMItemCount numSamplesInBuffer = CMSampleBufferGetNumSamples((__bridge CMSampleBufferRef)samples[i]); 
    AudioBufferList audioBufferList; 
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer((__bridge CMSampleBufferRef)samples[i], 
                  NULL, 
                  &audioBufferList, 
                  sizeof(audioBufferList), 
                  NULL, 
                  NULL, 
                  kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, 
                  &buffer 
                  ); 

    for (int bufferCount = 0; bufferCount < audioBufferList.mNumberBuffers; bufferCount++) { 
     SInt16* samples = (SInt16 *)audioBufferList.mBuffers[bufferCount].mData; 
     for (int i=0; i < numSamplesInBuffer; i++) { 
      // amplitude for the sample is samples[i], assuming you have linear pcm to start with 

      // (2) What should I be doing to write the samples into an audio file? 
     } 
    } 
    CFRelease(buffer); 
} 
+0

サンプルを '//すべてのサンプルを取得する 'の後に元に戻すとどうなりますか? – Guig

+0

@Guigええ、問題は '//(2)どうしたらいいですか? '私は単一のオーディオファイルにサンプルを書き込む方法がわかりません:/ –

答えて

1

はい、オーディオファイルのいずれかがいるiOSのサポートがあり、その後、あなたが処理できる方法、輸出があります。

ただし、これらの形式のほとんど(mp3は名前を1にする)はロッシーで圧縮されています。最初にデータの解凍、変換の適用、および再圧縮を行う必要があります。オーディオ情報に適用するほとんどの変換は、生のPCMレベルで行われるはずです。あなたは、いくつかのパスでこれを行うには、これらの二つの文を組み合わせる

  1. 一時ファイルが(その内容をリバース)AIFF
  2. プロセスのように、kAudioFormatLinearPCM準拠したオーディオファイルに元のファイルを変換します一時ファイルを元の形式に戻す

圧縮されたjpegイメージに変換を適用した場合と同じように、プロセスが劣化します。最終的なオーディオはせいぜいもう1つの圧縮サイクルを迎えます。

したがって、このアプローチに対する真の数学的な答えは実際には「いいえ」です。


参考のため、ここにswift 3のスターターコードをいくつか示します。ファイルヘッダーをスキップするには、さらに細かい調整が必要です。

var outAudioFile:AudioFileID? 
var pcm = AudioStreamBasicDescription(mSampleRate: 44100.0, 
             mFormatID: kAudioFormatLinearPCM, 
             mFormatFlags: kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger, 
             mBytesPerPacket: 2, 
             mFramesPerPacket: 1, 
             mBytesPerFrame: 2, 
             mChannelsPerFrame: 1, 
             mBitsPerChannel: 16, 
             mReserved: 0) 

var theErr = AudioFileCreateWithURL(destUrl as CFURL!, 
            kAudioFileAIFFType, 
            &pcm, 
            .eraseFile, 
            &outAudioFile) 
if noErr == theErr, let outAudioFile = outAudioFile { 
    var inAudioFile:AudioFileID? 
    theErr = AudioFileOpenURL(sourceUrl as! CFURL, .readPermission, 0, &inAudioFile) 

    if noErr == theErr, let inAudioFile = inAudioFile { 

     var fileDataSize:UInt64 = 0 
     var thePropertySize:UInt32 = UInt32(MemoryLayout<UInt64>.stride) 
     theErr = AudioFileGetProperty(inAudioFile, 
             kAudioFilePropertyAudioDataByteCount, 
             &thePropertySize, 
             &fileDataSize) 

     if(noErr == theErr) { 
      let dataSize:Int64 = Int64(fileDataSize) 
      let theData = UnsafeMutableRawPointer.allocate(bytes: Int(dataSize), 
                  alignedTo: MemoryLayout<UInt8>.alignment) 

      var readPoint:Int64 = Int64(dataSize) 
      var writePoint:Int64 = 0 

      while(readPoint > 0) 
      { 
       var bytesToRead = UInt32(2) 

       AudioFileReadBytes(inAudioFile, false, readPoint, &bytesToRead, theData) 
       AudioFileWriteBytes(outAudioFile, false, writePoint, &bytesToRead, theData) 

       writePoint += 2 
       readPoint -= 2 
      } 

      theData.deallocate(bytes: Int(dataSize), alignedTo: MemoryLayout<UInt8>.alignment) 

      AudioFileClose(inAudioFile); 
      AudioFileClose(outAudioFile); 
     } 
    } 
} 
+0

とても助けてくれてありがとう!私はかなり長い間これに固執してきました。私は.m4aから.aiffにオーディオファイルを変換しようとしましたが、何らかの理由でそれが動作していません。私は[別の質問](http://stackoverflow.com/questions/41436229/converting-m4a-file-to-aiff-using-audioconverter-swift)に尋ねたことがありますか? –

関連する問題