Frage an ios, audio, avassetwriter – Audio mit AVAssetWriter aufnehmen und wiedergeben

1

Ich habe diese Frage ein wenig reduziert und hoffe auf Hilfe.

Grundsätzlich hat diese Klasse zwei Methoden, eine zum Starten der Audioaufnahme (-recordMode) und die andere, um Audio abzuspielen (playMode). Ich habe derzeit diese Klasse in einem Projekt mit einem einzelnen View-Controller mit zwei Schaltflächen, die die entsprechenden Methoden aufrufen (rec, play). Es gibt keine anderen Variablen, die Klasse ist in sich geschlossen.

Es wird jedoch nichts abgespielt / aufgenommen und ich kann nicht herausfinden, warum. Wenn ich versuche, die Datei abzuspielen, erhalte ich eine Dateigröße von 0 und einen Fehler, weil Sie das nicht einleiten könnenAVAudioPlayer mit einernil Referenz natürlich. Aber ich verstehe nicht, warum die Datei leer ist oder warumself.outputPath istnil.

.h Datei

#import <AVFoundation/AVFoundation.h>

@interface MicCommunicator : NSObject<AVCaptureAudioDataOutputSampleBufferDelegate>

@property(nonatomic,retain) NSURL *outputPath;
@property(nonatomic,retain) AVCaptureSession * captureSession;
@property(nonatomic,retain) AVCaptureAudioDataOutput * output;

-(void)beginStreaming;
-(void)playMode;
-(void)recordMode;

@end

.m Datei:

@implementation MicCommunicator {
    AVAssetWriter *assetWriter;
    AVAssetWriterInput *assetWriterInput;
}

@synthesize captureSession = _captureSession;
@synthesize output = _output;
@synthesize outputPath = _outputPath;

-(id)init {
    if ((self = [super init])) {
        NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        self.outputPath = [NSURL fileURLWithPath:[[searchPaths objectAtIndex:0] stringByAppendingPathComponent:@"micOutput.output"]];

        AudioChannelLayout acl;
        bzero(&acl, sizeof(acl));
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; //kAudioChannelLayoutTag_Stereo;
        NSDictionary *audioOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                             [NSNumber numberWithInt: kAudioFormatULaw],AVFormatIDKey,        
                                             [NSNumber numberWithFloat:8000.0],AVSampleRateKey,//was 44100.0
                                             [NSData dataWithBytes: &acl length: sizeof( AudioChannelLayout ) ], AVChannelLayoutKey,
                                             [NSNumber numberWithInt:1],AVNumberOfChannelsKey,
                                             [NSNumber numberWithInt:8000.0],AVEncoderBitRateKey,
                                             nil];

        assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings];
        [assetWriterInput setExpectsMediaDataInRealTime:YES];

        assetWriter = [[AVAssetWriter assetWriterWithURL:_outputPath fileType:AVFileTypeWAVE error:nil] retain];
        [assetWriter addInput:assetWriterInput];
    }
    return self;
}

-(void)dealloc {
    [assetWriter release];
    [super dealloc];
}

//conveniance methods

-(void)playMode
{
    [self stopRecording];

    NSError *error;
    AVAudioPlayer * audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:self.outputPath error:&error];
    audioPlayer.numberOfLoops = -1;

    if (audioPlayer == nil){
        NSLog(@"error: %@",[error description]);        
    }else{ 
        NSLog(@"playing");  
        [audioPlayer play];
    }
}

-(void)recordMode
{
        [self beginStreaming];    
}

-(void)stopRecording
{
    [self.captureSession stopRunning];
    [assetWriterInput markAsFinished];
    [assetWriter  finishWriting];

    NSDictionary *outputFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:@"%@",self.outputPath] error:nil];
    NSLog (@"done. file size is %llu", [outputFileAttributes fileSize]);
}

//starts audio recording
-(void)beginStreaming {
    self.captureSession = [[AVCaptureSession alloc] init];
    AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    NSError *error = nil;
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error];
    if (audioInput)
        [self.captureSession addInput:audioInput];
    else {
        NSLog(@"No audio input found.");
        return;
    }

    AVCaptureAudioDataOutput *output = [[AVCaptureAudioDataOutput alloc] init];

    dispatch_queue_t outputQueue = dispatch_queue_create("micOutputDispatchQueue", NULL);
    [output setSampleBufferDelegate:self queue:outputQueue];
    dispatch_release(outputQueue);

    [self.captureSession addOutput:output];
    [assetWriter startWriting];
    [self.captureSession startRunning];
}

//callback
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    AudioBufferList audioBufferList;
    NSMutableData *data= [[NSMutableData alloc] init];
    CMBlockBufferRef blockBuffer;
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &blockBuffer);

    //for (int y = 0; y < audioBufferList.mNumberBuffers; y++) {
    //  AudioBuffer audioBuffer = audioBufferList.mBuffers[y];
    //  Float32 *frame = (Float32*)audioBuffer.mData;
    //          
    //  [data appendBytes:frame length:audioBuffer.mDataByteSize];
    //}

    // append [data bytes] to your NSOutputStream 


    // These two lines write to disk, you may not need this, just providing an example
    [assetWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];
    [assetWriterInput appendSampleBuffer:sampleBuffer];

    CFRelease(blockBuffer);
    blockBuffer=NULL;
    [data release];
}

@end
Ich nehme diese Aussage zurück. Die while-Schleife bewirkt nichts im Hinblick auf das Speichern des Audios in einer Datei owen gerig
Ja, ich weiß so viel, weil ich es benutze, um die Audiodaten an eine andere Klasse zu senden, um diese Audiodaten zu streamen. und es würde konsequent aufgerufen werden. Wie ich schon sagte, dies ist eine Art heruntergekommene Version, also habe ich das entfernt. In jedem Fall werde ich dies durchgehen und einige Dinge wie Ihr Sprichwort hinzufügen, danke für den Vorschlag owen gerig
huh wenn ich NSLog setze (@ "Anzahl der Puffer% d", y); In der for-Schleife innerhalb des Callbacks ist es immer 0. Dies bedeutet, dass mNumberBuffers ebenfalls 0 ist owen gerig
scheint so (stackoverflow.com/a/4299665/530933) könnte mein Problem sein. Scheint als wären die Samples 8 Bit oder? owen gerig

Deine Antwort

1   die antwort
0

Dies ist daher der Fehler - die Datei wird erstellt, eine Reihe von Samples werden erfolgreich geschrieben und das Anhängen schlägt aus einem unbekannten Grund fehl.

Es scheint, dass AVAssetWriter nur mit diesen Einstellungen fehlschlägt.

AudioQueue sollte für ulaw-Audio verwendet werden

Wurde dieser Fehler jemals von Apple behoben? TigerCoding
Wirklich nicht sicher, ob ich das zu einem so späten Zeitpunkt nachprüfen kann. Wenn Ihnen dieses Zeug wirklich Probleme bereitet, ist es möglicherweise ratsam, einen Ihrer kostenlosen Support-Fälle für die Entwicklung von Apple zu verwenden owen gerig

Verwandte Fragen