Cordova iOS - 即使创建了文件,也无法录制媒体

时间:2017-06-05 11:55:31

标签: ios xcode cordova cordova-plugins phonegap

我正在尝试使用cordova-plugin-media录制声音文件,但我总是收到此错误:

  

{message:"无法初始化AVAudioRecorder :( null)↵",代码:1}

我首先创建文件,就像这样

iOSCreateFile(fileName, callback) {
    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, (fs) => {
        fs.root.getFile(fileName, {
            create: true, 
            exclusive: false
        }, (fileEntry) => {
            console.log("fileEntry is file?" + fileEntry.isFile.toString());
            // here I am getting true, so the file is obviously created
            callback(fileEntry.nativeURL);
        }, (error) => {
            console.log('error create file: ' + error);
        });
    }, (error) => {
        console.log('error loading file system: ' + error);
    });
},

我发回的fileEntry.nativeURL看起来像这样

file:///var/mobile/Containers/Data/Application/0EE019AA-EFBA-4FB9-97EC-1F16FFDDA36B/tmp/1496663387924.wav

然后,当回调时,我正在做以下

// that long file path string is passed here
let soundRecord = new Media(filePath, () => {
    // success
    // more code
}, (error) => {
    console.log(error);
});

一旦它尝试执行新语句,它就会给我初始化AVAudioRecorder错误...

我做错了什么?

编辑:我也尝试过不创建文件,只是将文件名字符串传递给新的Media对象,例如" 1240215251.wav",它应该为我创建它,但我仍然得到同样的错误。

更新:我试图捕获本机代码中的错误,但我不太了解它,当我调试时我只能看到生成错误的位置,但没有别的,请检查在代码下面,我已经评论了需要的地方

- (void)startRecordingAudio:(CDVInvokedUrlCommand*)command {
    NSString* callbackId = command.callbackId;

#pragma unused(callbackId)

    NSString* mediaId = [command argumentAtIndex:0];
    CDVAudioFile* audioFile = [self audioFileForResource:[command argumentAtIndex:1] withId:mediaId doValidation:YES forRecording:YES];
    __block NSString* jsString = nil;
    __block NSString* errorMsg = @"";

    if ((audioFile != nil) && (audioFile.resourceURL != nil)) {
        __weak CDVSound* weakSelf = self;
        void (^startRecording)(void) = ^{
            NSError* __autoreleasing error = nil;
            if (audioFile.recorder != nil) {
                [audioFile.recorder stop];
                audioFile.recorder = nil;
            }
            if ([weakSelf hasAudioSession]) {
                if (![weakSelf.avSession.category isEqualToString:AVAudioSessionCategoryPlayAndRecord]) {
                    [weakSelf.avSession setCategory:AVAudioSessionCategoryRecord error:nil];
                }

                if (![weakSelf.avSession setActive:YES error:&error]) {
                    // other audio with higher priority that does not allow mixing could cause this to fail
                    errorMsg = [NSString stringWithFormat:@"Unable to record audio: %@", [error localizedFailureReason]];
                    // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_ABORTED];
                    jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [weakSelf createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]];
                    [weakSelf.commandDelegate evalJs:jsString];
                    return;
                }
            }
            NSDictionary *audioSettings = @{AVFormatIDKey: @(kAudioFormatMPEG4AAC),
                                             AVSampleRateKey: @(44100),
                                             AVNumberOfChannelsKey: @(1),
                                             AVEncoderAudioQualityKey: @(AVAudioQualityMedium)
                                             };
            audioFile.recorder = [[CDVAudioRecorder alloc] initWithURL:audioFile.resourceURL settings:audioSettings error:&error];
            // HERE ^
            // Just after this audioFile.recorder declaration, the error variable below gets a value -  NSError *   domain:
            // @"NSOSStatusErrorDomain" - code: 1718449215  0x0000000170247e90

            bool recordingSuccess = NO;
            if (error == nil) {
                audioFile.recorder.delegate = weakSelf;
                audioFile.recorder.mediaId = mediaId;
                audioFile.recorder.meteringEnabled = YES;
                recordingSuccess = [audioFile.recorder record];
                if (recordingSuccess) {
                    NSLog(@"Started recording audio sample '%@'", audioFile.resourcePath);
                    jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_RUNNING];
                    [weakSelf.commandDelegate evalJs:jsString];
                }
            }

            if ((error != nil) || (recordingSuccess == NO)) {
                // It then enters in one of below cases
                if (error != nil) {
                    errorMsg = [NSString stringWithFormat:@"Failed to initialize AVAudioRecorder: %@\n", [error localizedFailureReason]];
                } else {
                    errorMsg = @"Failed to start recording using AVAudioRecorder";
                }
                audioFile.recorder = nil;
                if (weakSelf.avSession) {
                    [weakSelf.avSession setActive:NO error:nil];
                }
                jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [weakSelf createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]];
                [weakSelf.commandDelegate evalJs:jsString];
            }
        };
        ...
        // More irrelevant code of the method
        ...
}

2 个答案:

答案 0 :(得分:1)

我认为插件无法创建AVAudioRecorder,因为您传递的是nativeURL,我不知道是否支持。你试过quick-examples之一吗?无需事先通过iOSCreateFile手动创建文件。

答案 1 :(得分:1)

由于使用了cordova媒体插件VERSION 3.0.0,可能会发生这个问题。此版本在iOS中录制“wav”文件时出现问题。媒体插件的官方问题跟踪器中已经引发issue,并在VERSION 3.0.1中修复了

因此升级到最新版本的插件应解决此问题。在这个特殊情况下,插件在第一次尝试时不会正确安装。希望它能解决正确升级的问题。干杯