iOS 5 - AVAPlayer больше не работает - PullRequest
0 голосов
/ 25 ноября 2011

У меня есть немного кода, который работал нормально с iOS 4.3.Я заглянул в Интернет, я обнаружил, что у других были те же проблемы без ответа, который работал для меня.Я думаю, что могу что-то записать, но не могу это воспроизвести.Вот мой код:

DetailViewController.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>
#import <AudioToolbox/AudioServices.h>

@interface DetailViewController : UIViewController <UISplitViewControllerDelegate, AVAudioRecorderDelegate> {

id detailItem;
UILabel *detailDescriptionLabel;

IBOutlet UIButton *btnStart;
IBOutlet UIButton *btnPlay;

//Variables setup for access in the class:
NSURL * recordedTmpFile;
AVAudioRecorder * recorder;
BOOL toggle;
}

// Needed properties
@property (nonatomic, retain) IBOutlet UIButton *btnStart;
@property (nonatomic, retain) IBOutlet UIButton *btnPlay;
@property (strong, nonatomic) id detailItem;
@property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;

-(IBAction) start_button_pressed;
-(IBAction) play_button_pressed;
@end

DetailViewController.m

- (void)viewDidLoad {
[super viewDidLoad];
toggle = YES;
btnPlay.hidden = YES;
NSError *error;

// Create the Audio Session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];

// Set up the type of session
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];

// Activate the session.
[audioSession setActive:YES error:&error];

[self configureView];    
}

-(IBAction) start_button_pressed{
if (toggle) {
    toggle = NO;
    [btnStart setTitle:@"Press to stop recording" forState:UIControlStateNormal];
    btnPlay.enabled = toggle;
    btnPlay.hidden = !toggle;
            NSError *error;

    NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];

    [recordSettings setValue:[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];

    [recordSettings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];

    [recordSettings setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];

    // Create a temporary files to save the recording. 
    recordedTmpFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat: @"%.0f.%@", [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"caf"]]];

    NSLog(@"The temporary file used is: %@", recordedTmpFile);

    recorder = [[AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSettings error:&error];

    [recorder setDelegate:self];

    [recorder prepareToRecord];
    [recorder record];
}
else {
    toggle = YES;
    [btnStart setTitle:@"Start recording" forState:UIControlStateNormal];
    btnPlay.hidden = !toggle;
    btnPlay.enabled = toggle;

    NSLog(@"Recording stopped and saved in file: %@", recordedTmpFile);
    [recorder stop];
}
}

-(IBAction) play_button_pressed{

NSError *error;
AVAudioPlayer * avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:recordedTmpFile error:&error];

   if (!error)
   {
       [avPlayer prepareToPlay];
       [avPlayer play];

       NSLog(@"File is playing");
   }

}

- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player
                    successfully: (BOOL) flag {
     NSLog (@"audioPlayerDidFinishPlaying:successfully:");
}

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully: (BOOL)flag
{
    NSLog (@"audioRecorderDidFinishRecording:successfully:");
}

Вот моя запущенная программа:

2011-11-25 11: 58: 02.005 Bluetooth1 [897: 707] Используемый временный файл: file: //localhost/private/var/mobile/Applications/D81023F8-C53D-4AC4-B1F7-14D66EB4844A/tmp/343915082005.caf2011-11-25 11: 58: 05.956 Bluetooth1 [897: 707] Запись остановлена ​​и сохранена в файле: file: // localhost / private / var / mobile / Applications / D81023F8-C53D-4AC4-B1F7-14D66EB4844A / tmp / 343915082005.caf 2011-11-25 11: 58: 05.998 Bluetooth1 [897: 707] audioRecorderDidFinishRecording: успешно: 2011-11-25 11: 58: 11.785 Bluetooth1 [897: 707] Файл воспроизводится

По какой-то причине, функция audioPlayerDidFinishPlaying никогда не вызывается.Однако, похоже, что-то было записано.Прямо сейчас я не знаю, какая часть не работает, но я думаю, это как-то связано с AVAudioPlayer.

[EDIT] Становится все страннее и страннее.Я хотел убедиться, что что-то записано, поэтому я искал продолжительность записи.Вот новая функция воспроизведения:

-(IBAction) play_button_pressed{

    NSError *error;
AVAudioPlayer * avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: recordedTmpFile error:&error];

    if (!error)
    {
        AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:recordedTmpFile options:nil];
        CMTime audioDuration = audioAsset.duration;
        float audioDurationSeconds = CMTimeGetSeconds(audioDuration);

        [avPlayer prepareToPlay];
        [avPlayer play];

        NSString *something = [NSString stringWithFormat:@"%f",audioDurationSeconds]; 
        NSLog(@"File is playing: %@", something);
    }
    else
    {
         NSLog(@"Error playing.");
    }   
}

Теперь длина записи записывается, и это имеет смысл (если я записываю в течение 10 секунд, это показывает что-то около 10 секунд).Однако, когда я поместил эти строки кода в первый раз, я забыл выполнить преобразование с плавающей точкой в ​​NSString.Таким образом, он упал ... и приложение воспроизводит звук ... После различных тестов я могу сделать вывод, что мое приложение может записывать и воспроизводить звук, но в случае сбоя воспроизводить записанный звук.Я понятия не имею, в чем может быть проблема.Я обнаружил, что AVPlayer является асинхронным, это как-то связано с этим?Я полностью потерян ...

Ответы [ 3 ]

1 голос
/ 18 марта 2012

Замените urlpath следующим кодом:

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(
         NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filepath = [documentsDirectory stringByAppendingPathComponent:@"urfile.xxx"];

NSURL *url = [NSURL fileURLWithPath:filepath];
0 голосов
/ 09 декабря 2011

ОК, не очень круто отвечать на ваши вопросы. Более того, когда ответ не чистый, но он работает ... Чтобы воспроизвести то, что я записал, я использовал следующий блок кода:

    AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:recordedTmpFile options:nil];
    CMTime audioDuration = audioAsset.duration;
    float audioDurationSeconds = CMTimeGetSeconds(audioDuration);

    [avPlayer prepareToPlay];
    [avPlayer play];

    // Block for audioDurationSeconds seconds
    [NSThread sleepForTimeInterval:audioDurationSeconds];

Я рассчитываю длину записанного файла и жду этого количества времени ... он грязный, но делает свое дело. Плюс, если он запущен в другом потоке, он не будет блокировать приложение.

У кого-нибудь есть что-то, что я с радостью возьму!

0 голосов
/ 26 ноября 2011

Попробуйте решение здесь:

Запись и воспроизведение

...