xcode AVAudioPlayer 不播放 mp3?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12727672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 01:42:27  来源:igfitidea点击:

AVAudioPlayer doesn't play mp3?

iosxcodemp3avaudioplayer

提问by iWheelBuy

I want my AVAudioPlayerto play some mp3 files. It plays some of them but I have one file that can't be played!

我想AVAudioPlayer播放一些 mp3 文件。它可以播放其中一些,但我有一个文件无法播放!

To play the file I download it on my device into application folder and init it this way:

要播放文件,我将它下载到我的设备上的应用程序文件夹中并以这种方式初始化:

[[AVAudioPlayer alloc] initWithContentsOfURL:soundPath error:nil];

How to play the file? Why it doesn't play?

如何播放文件?为什么不播放?

Link to a file: abc.mp3

链接到文件:abc.mp3

EDIT:

编辑:

(Here is the code that shows the error. There is a README inside the code. Try on the device.)

(这是显示错误的代码。代码里面有一个 README。在设备上试试。)

***.pch

#import <Availability.h>

#ifndef __IPHONE_4_0
#warning "This project uses features only available in iOS SDK 4.0 and later."
#endif

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import <SystemConfiguration/SystemConfiguration.h>
    #import <MobileCoreServices/MobileCoreServices.h>
    #import <AVFoundation/AVFoundation.h>
    #import <AudioToolbox/AudioToolbox.h>
#endif



ViewController.h

#import <UIKit/UIKit.h>
#import "AFNetworking.h"

@interface SCRViewController : UIViewController <AVAudioPlayerDelegate>
{
    UIButton *button;
    __block UIProgressView *view;
    NSOperationQueue *queue;
    __block BOOL isFile;
    UIButton *play;
    NSString *path;
    AVAudioPlayer *_player;
}

@end


ViewController.m

#import "ViewController.h"

@implementation SCRViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setBackgroundColor:[UIColor yellowColor]];
    [button setFrame:CGRectMake(50, 50, 220, 50)];
    [button addTarget:self action:@selector(download) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"Download" forState:UIControlStateNormal];
    [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
    [self.view addSubview:button];

    play = [UIButton buttonWithType:UIButtonTypeCustom];
    [play setBackgroundColor:[UIColor yellowColor]];
    [play setFrame:CGRectMake(50, 150, 220, 50)];
    [play addTarget:self action:@selector(play) forControlEvents:UIControlEventTouchUpInside];
    [play setTitle:@"Play" forState:UIControlStateNormal];
    [play setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [play setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
    [self.view addSubview:play];

    self->view = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
    self->view.frame = CGRectMake(10, 120, 300, 20);
    [self->view setProgress:0];
    [self.view addSubview:self->view];

    queue = [[NSOperationQueue alloc] init];

    isFile = NO;
}

- (void) download
{
    [button setBackgroundColor:[UIColor brownColor]];
    [button setTitleColor:[UIColor whiteColor] forState:UIControlStateDisabled];
    [button setEnabled:NO];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://iwheelbuy.com/abc.mp3"]];

    //-------------------------------------------------------
    //-------------------------------------------------------
    // READ ME
    //-------------------------------------------------------
    //-------------------------------------------------------
    // Test in on device
    // I have uploaded another song for you. You can change link to http://iwheelbuy.com/def.mp3 and check the result
    // def.mp3 works fine on the device
    //-------------------------------------------------------
    //-------------------------------------------------------

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    path = [path stringByAppendingPathComponent:@"song"];

    if ( [[NSFileManager defaultManager] fileExistsAtPath:path])
        [[NSFileManager defaultManager] removeItemAtPath:path error:nil];

    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
     {
         isFile = YES;
     } failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
         //
     }];
    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
     {
         CGFloat done = (CGFloat)((int)totalBytesRead);
         CGFloat expected = (CGFloat)((int)totalBytesExpectedToRead);
         CGFloat progress = done / expected;
         self->view.progress = progress;
     }];
    [queue addOperation:operation];
}

- (void) play
{
    if (isFile)
    {
        NSError *error = nil;
        NSURL *url = [NSURL fileURLWithPath:path];
        _player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
        if(error || !_player)
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:[error description] delegate:nil cancelButtonTitle:@"Try def.mp3" otherButtonTitles:nil];
            [alert show];
        }
        else
        {
            [_player play]; // plays fine
            [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
            [[AVAudioSession sharedInstance] setActive: YES error: nil];
        }
    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"Download the file plz" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
        [alert show];
    }
}

@end

采纳答案by iWheelBuy

http://bugreport.apple.com

Engineering has determined that this issue behaves as intended based on the following information:

工程已根据以下信息确定此问题的行为符合预期:

Could repro with attached sample app, but this is an expected behavior from AudioFile.

可以使用附加的示例应用程序重现,但这是 AudioFile 的预期行为。

The issue is that AVAudioPlayeris being initialized with a url without a file extension and the corresponding file does not have a valid ID3tag.Without a file extension or valid data, we cannot determine the right file format and hence such files will fail to open.This is an expected behavior.

问题是AVAudioPlayer正在使用没有文件扩展名的 url 进行初始化,并且相应的文件没有有效的ID3标签。没有文件扩展名或有效数据,我们无法确定正确的文件格式,因此此类文件将无法打开。此是预期的行为。

In the sample code attached:

在所附的示例代码中:

path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

path = [path stringByAppendingPathComponent:@"song"];

--> path will be something like:

--> 路径类似于:

/var/mobile/Applications/2FFD0147-E56B-47D4-B143-A9F19BE92818/Documents/song

/var/mobile/Applications/2FFD0147-E56B-47D4-B143-A9F19BE92818/Documents/song

--> NOTE: no file extension at the end.

--> 注意:最后没有文件扩展名。

abc.mp3 has an invalid ID3tag size (0x2EE) unlike def.mp3 which has a valid tag size (0x927). Hence when these are specified as "…./song" without any extension, AudioFile just looks at the data and finds a valid sync word for def.mp3 but not for abc.mp3.

abc.mp3 有一个无效的ID3标签大小 (0x2EE),不像 def.mp3 有一个有效的标签大小 (0x927)。因此,当这些被指定为没有任何扩展名的“..../song”时,AudioFile 只是查看数据并找到 def.mp3 的有效同步字,而不是 abc.mp3。

However, replacing stringByAppendingPathComponent:@"song"with stringByAppendingPathComponent:@"song.mp3"succeeds for abc.mp3, and could help for other mp3 files in general.

但是,更换stringByAppendingPathComponent:@"song"stringByAppendingPathComponent:@"song.mp3"成功的abc.mp3,并能帮助其他一般的MP3文件。

We consider this issue closed. If you have any questions or concern regarding this issue, please update your report directly (http://bugreport.apple.com).

我们认为这个问题已经结束。如果您对此问题有任何疑问或疑虑,请直接更新您的报告 ( http://bugreport.apple.com)。

Thank you for taking the time to notify us of this issue.

感谢您抽出宝贵时间通知我们此问题。

回答by HKTonyLee

Non-ARC

非ARC

You have to retain it during playback because it does not retain itself. It will stop playing instantly once it is dealloc-ed.

您必须在播放期间保留它,因为它不会保留自身。一旦解除分配,它将立即停止播放。

ARC

You need to hold the AVAudioPlayerinstance in the class. And release it after it stops playing. For example,

您需要AVAudioPlayer在类中保存实例。并在停止播放后释放它。例如,

#import <AVFoundation/AVFoundation.h>

@interface TAViewController () <AVAudioPlayerDelegate> {
    AVAudioPlayer *_somePlayer;   // strong reference
}
@end

@implementation TAViewController

- (IBAction)playAudio:(id)sender
{
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"kogmawjoke" withExtension:@"mp3"];
    _somePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
    _somePlayer.delegate = self;
    [_somePlayer play];
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    if (player == _somePlayer) {
        _somePlayer = nil;
    }
}

@end