简体   繁体   English

iOS 5-AVAPlayer不再起作用

[英]iOS 5 - AVAPlayer not working anymore

I've a bit of code which was working fine with iOS 4.3. 我有一些代码可以在iOS 4.3上正常工作。 I had a look on the Internet, I found others having the same problem without answer which worked for me. 我在互联网上看了一下,发现其他人也遇到了同样的问题而没有答案,这对我很有效。 I think that I can record something but I cannot play it. 我认为我可以录制某些东西,但不能播放。 Here is my code: 这是我的代码:

DetailViewController.h 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 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:");
}

Here is the of my program running: 这是我的程序正在运行:

2011-11-25 11:58:02.005 Bluetooth1[897:707] The temporary file used is: file://localhost/private/var/mobile/Applications/D81023F8-C53D-4AC4-B1F7-14D66EB4844A/tmp/343915082005.caf 2011-11-25 11:58:05.956 Bluetooth1[897:707] Recording stopped and saved in file: 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:successfully: 2011-11-25 11:58:11.785 Bluetooth1[897:707] File is playing 2011-11-25 11:58:02.005 Bluetooth1 [897:707]使用的临时文件是:file:// localhost / private / var / mobile / Applications / D81023F8-C53D-4AC4-B1F7-14D66EB4844A / tmp / 343915082005。 caf 2011-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]文件正在播放

For some reason, the function audioPlayerDidFinishPlaying is never called. 由于某些原因,永远不会调用函数audioPlayerDidFinishPlaying。 However it seems that something has been recorded. 但是,似乎已记录了一些内容。 Right now I do not know which part is not working but I guess this has something to do with AVAudioPlayer. 现在,我不知道哪个部分不起作用,但是我想这与AVAudioPlayer有关。

[EDIT] It's getting weirder and weirder. [编辑]越来越奇怪了。 I wanted to make sure that something was recorded so I look for taking the duration of the record. 我想确保记录了一些内容,因此我希望保留记录的持续时间。 Here is the new play function: 这是新的播放功能:

-(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.");
    }   
}

Now, the length of the record is recorded and it make sense (if I record for 10s it shows something around 10s). 现在,记录的长度被记录下来并且很有意义(如果我记录10s,它显示大约10s)。 However, when I put these lines of code for the first time I forgot to do the conversion float to NSString. 但是,当我第一次放置这些代码行时,我忘记了将转换浮点数转换为NSString。 So it crashed... and the app play the sound... After different tests I can conclude that my app can record and play a sound but is as to crash to play the recorded sound. 因此它崩溃了……该应用程序播放了声音……经过不同的测试,我可以得出结论,我的应用程序可以录制和播放声音,但是会崩溃以播放录制的声音。 I've no idea what can be the problem. 我不知道可能是什么问题。 I found that AVPlayer is asynchronous, is their something to do with that? 我发现AVPlayer是异步的,这与它们有关吗? I'm completely lost... 我完全迷路了...

Replace the urlpath with the following code: 用以下代码替换urlpath:

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

NSURL *url = [NSURL fileURLWithPath:filepath];

Try the solution here: 在这里尝试解决方案:

Recording and playback 录制和播放

OK, that is not really cool to answer you own questions. 好的,回答您自己的问题并不是很酷。 Moreover when the answer is not clean but it is working... In order to play what I have recorded I have used the following block of code: 而且,当答案不是很干净但是可以正常工作时...为了播放我记录的内容,我使用了以下代码块:

    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];

I am calculating the length of the recorded file and I am waiting for this amount of time... it is dirty but it is doing the trick. 我正在计算记录文件的长度,我正在等待这段时间...虽然很脏,但是可以解决问题。 Plus, if it launched in another thread it will not block the application. 另外,如果它在另一个线程中启动,则不会阻止该应用程序。

I anyone has something I would gladly take it! 我有人有我愿意接受的东西!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM