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
AVAudioPlayer doesn't play mp3?
提问by iWheelBuy
I want my AVAudioPlayer
to 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 AVAudioPlayer
is being initialized with a url without a file extension and the corresponding file does not have a valid ID3
tag.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 ID3
tag 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 AVAudioPlayer
instance 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