奇怪的问题在app中加载音频文件

时间:2015-11-11 19:03:21

标签: ios objective-c iphone audio

我在我的应用中加载某些音频文件时遇到问题,某些歌曲/音频会正常工作,有些则没有,我无法弄清楚如何或为什么。

当它是基于云的iTunes音乐时,它无法确定,但主要是如果音乐已经从iTunes下载到设备,它将加载,但即便如此,一些文件只是拒绝加载。

这是代码,用于打开;

#define EXPORT_NAME @"exported.m4a"

- (void) openSoundFile:(ProductInfo*)info
{
    [self dismissViewControllerAnimated:YES completion:nil];

    if (currentProduct) {
        [currentProduct release];
        currentProduct = nil;
    }
    currentProduct = [[ProductInfo alloc] init];

    currentProduct.index = info.index;
    currentProduct.parent = info.parent;
    currentProduct.title = [info.title copy];
    currentProduct.name = [info.name copy];
    currentProduct.tempo = info.tempo;
    currentProduct.pitch = info.pitch;
    currentProduct.key = info.key;

    [m_lblName setText:info.title];

    [m_viewIsLoading setHidden:NO];
    [self loadSoundFileToM4A];
}

然后我们展示loadSoundFileToM4A方法;

-(void) loadSoundFileToM4A 
{
    NSURL *assetURL = [NSURL URLWithString:currentProduct.name];
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];

    AVAssetExportSession *exporter = [[AVAssetExportSession alloc]
                                      initWithAsset: songAsset
                                      presetName: AVAssetExportPresetAppleM4A];

    exporter.outputFileType = @"com.apple.m4a-audio";


    // set up export (hang on to exportURL so convert to PCM can find it)
    NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
    NSString *exportPath = [[documentsDirectoryPath stringByAppendingPathComponent:EXPORT_NAME] retain];
    if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
        [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
    }
    NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
    exporter.outputURL = exportURL; 

    // do the export
    [exporter exportAsynchronouslyWithCompletionHandler:^{
        int exportStatus = exporter.status;
        switch (exportStatus) {
            case AVAssetExportSessionStatusFailed: {
                // log error to text view
                NSError *exportError = exporter.error;
                NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError);
                [self loadSoundFileFail];
                break;
            }
            case AVAssetExportSessionStatusCompleted: {
                NSLog (@"AVAssetExportSessionStatusCompleted");
                // set up AVPlayer
                [self loadSoundFile];
                break;
            }

            case AVAssetExportSessionStatusUnknown: { NSLog (@"AVAssetExportSessionStatusUnknown"); break;}
            case AVAssetExportSessionStatusExporting: { NSLog (@"AVAssetExportSessionStatusExporting"); break;}
            case AVAssetExportSessionStatusCancelled: { NSLog (@"AVAssetExportSessionStatusCancelled"); break;}
            case AVAssetExportSessionStatusWaiting: { NSLog (@"AVAssetExportSessionStatusWaiting"); break;}
            default: { NSLog (@"didn't get export status"); break;}
        }
    }];
}

失败时,它使用此方法;

- (void) loadSoundFileFail
{
    [m_viewIsLoading setHidden:YES];
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Failed"
                                              message:@"Couldn't load file"
                                             delegate:self 
                                    cancelButtonTitle:nil 
                                    otherButtonTitles:@"OK", nil];
    [alert show];
}

成功时,这就是方法;

- (void) loadSoundFile
{
    [m_viewIsLoading setHidden:YES];

    NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
    NSString *exportPath = [[documentsDirectoryPath stringByAppendingPathComponent:EXPORT_NAME] retain];

    if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
        if( m_pPlayer != NULL )
        {
            if( m_pPlayer->IsRunning() )
            {
                OSStatus result = m_pPlayer->StopQueue();
                if (result == noErr)
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"soundQueueResumed" object:self];
            }

            m_pPlayer->DisposeQueue( TRUE );

            CFStringRef strFilePath = (CFStringRef)exportPath;
            m_pPlayer->CreateQueueForFile( strFilePath );

            nTempo = (float)currentProduct.tempo;
            nPitch = (float)currentProduct.pitch/100.0f;
            nKey = (float)currentProduct.key;

            [self setKeyValue];
            [self setTempoValue];
            [self setPitchValue];

            [m_sldTempo setValue:nTempo];
            [m_sldPitch setValue:nPitch];
            [m_sldKey setValue:nKey];

            [self setRepeatSwitchState];
            [self setReverseSwitchState];

            // Set the button's state back to "record"
            if( m_pPlayer->Queue() == NULL )
                m_btnPlay.enabled = NO;
            else
                m_btnPlay.enabled = YES;
        }
    }
}

我在调试器中捕获了这个错误;

 AVAssetExportSessionStatusFailed: Error Domain=NSURLErrorDomain Code=-1 "unknown error" 
UserInfo=0x1700ffa80 {NSUnderlyingError=0x17804edf0 "The operation couldn’t be completed. 
(OSStatus error -12935.)", NSErrorFailingURLStringKey=(null), NSErrorFailingURLKey=(null), NSURL=(null), 
NSLocalizedDescription=unknown error}

0 个答案:

没有答案