AVAudioPlayer 不播放 mp3?
Posted
技术标签:
【中文标题】AVAudioPlayer 不播放 mp3?【英文标题】:AVAudioPlayer doesn't play mp3? 【发布时间】:2012-10-04 12:48:24 【问题描述】:我想让我的AVAudioPlayer
播放一些 mp3 文件。它可以播放其中一些,但我有一个文件无法播放!
要播放我在设备上下载的文件到应用程序文件夹并以这种方式初始化:
[[AVAudioPlayer alloc] initWithContentsOfURL:soundPath error:nil];
如何播放文件?为什么不播放?
文件链接:abc.mp3
编辑:
(这是显示错误的代码。代码中有一个 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
【问题讨论】:
AVAudioPlayer doesn't load sound的可能重复 【参考方案1】:非 ARC
您必须在播放期间保留它,因为它不会自行保留。一旦被释放,它将立即停止播放。
ARC
您需要在类中保存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
【讨论】:
其他歌曲播放良好!只有这个不想玩! 我在 iPhone 4S (iOS6) 和 iOS6 模拟器上试过你的音频,但都可以播放。能否提供更多关于测试环境的信息? 您是否已将歌曲下载到您的设备/模拟器?或者您使用了指向这首歌的直接链接? 我把它下载到了项目中。编译时将其复制到.app。并使用 NSBundle 获取文件的路径。 hm... 我在应用程序运行时下载它。并将其保存在应用程序的 Documents 文件夹中。也许这就是问题所在?!【参考方案2】:http://bugreport.apple.com
工程部门已根据以下信息确定此问题的行为符合预期:
可以使用附加的示例应用进行重现,但这是 AudioFile 的预期行为。
问题是AVAudioPlayer
正在初始化一个没有文件扩展名的url,并且对应的文件没有有效的ID3
标签。没有文件扩展名或有效数据,我们无法确定权利文件格式,因此此类文件将无法打开。这是预期的行为。
在附上的示例代码中:
path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
path = [path stringByAppendingPathComponent:@"song"];
--> 路径类似于:
/var/mobile/Applications/2FFD0147-E56B-47D4-B143-A9F19BE92818/Documents/song
--> 注意:末尾没有文件扩展名。
abc.mp3 有一个无效的ID3
标签大小 (0x2EE),而 def.mp3 有一个有效的标签大小 (0x927)。因此,当这些被指定为没有任何扩展名的“..../song”时,AudioFile 只会查看数据并为 def.mp3 找到一个有效的同步字,而不是为 abc.mp3 找到一个有效的同步字。
但是,对于 abc.mp3,将 stringByAppendingPathComponent:@"song"
替换为 stringByAppendingPathComponent:@"song.mp3"
是成功的,并且通常有助于其他 mp3 文件。
我们认为此问题已解决。如果您对此问题有任何疑问或疑虑,请直接更新您的报告 (http://bugreport.apple.com)。
感谢您抽出宝贵时间将此问题通知我们。
【讨论】:
以上是关于AVAudioPlayer 不播放 mp3?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 AVAudioPlayer 从时间 t1 到 t2 在 Xcode 中播放 mp3 文件
本地文件使用 AVAudioPlayer 播放,但不使用 AVPlayer?
使用 AVAudioPlayer 在 Swift 中播放远程 mp3 文件