首先,为了避免在这里发布大量代码,我创建了一个非常基本的例子来说明我所追求的内容 - https://github.com/opheliadesign/AudioTest。
我是iOS开发的新手,我在理解在远程服务器上加载和播放静态MP3文件的最佳方式时遇到了一些麻烦。音频不直播,小于一兆字节 - 平均约30秒(它们是无线电调度)。
有人建议我使用NSURLSession加载MP3文件,然后在完成块中播放。这似乎有效,但我有一种感觉,我可以更好地处理它,只是不知道如何。这是我抓住音频并开始播放的块:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
NSLog(@"View loaded");
// Register to receive notification from AppDelegate when entering background
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopPlayingAudio) name:@"stopPlayingAudio" object:nil];
// Assign timer to update progress
self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateSeekBar) userInfo:nil repeats:YES];
// Demo recording URL
NSString *recordingUrl = @"https://s3.amazonaws.com/tevfd-recording/All_Fire_and_EMS_2015-02-0214_48_33_630819.mp3";
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:recordingUrl] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSLog(@"No error..");
self.player = [[AVAudioPlayer alloc]initWithData:data error:nil];
// Setup slider for track position
self.slider.minimumValue = 0;
self.slider.maximumValue = self.player.duration;
[self.player prepareToPlay];
[self.player play];
}
}]resume];
}
例如,有一个滑块可以在移动时更新玩家的位置。我在完成块中初始化AVAudioPlayer,但在标题中为它创建了一个属性。如果播放器尚未初始化,移动滑块会导致崩溃吗?如果是这样,我该如何更好地处理这个?
另外,我有一个计时器,可以在AVAudioPlayer播放时更新滑块位置。当轨道到达终点时,计时器继续 - 显然这是一个潜在的内存问题。不确定处理此问题的最佳方法,我也希望用户能够在完成后再次开始播放录制内容,例如,如果他们将滑块移动到右侧。
我已经搜索过,无法找到与我正在做的事情有关的任何事情。任何帮助将不胜感激。
更新 这是我最初开始的,但是我在点击UITableView单元格和呈现加载/播放音频的视图之间经历了一些延迟。有几个人提出了NSURLSession。
- (void)viewDidLoad {
[super viewDidLoad];
// Get the URL
NSURL *callAudioURL = [NSURL URLWithString:[self.call objectForKey:@"url"]];
NSData *callAudioData = [NSData dataWithContentsOfURL:callAudioURL];
AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithData: callAudioData error:nil];
self.player = audio;
self.slider.minimumValue = 0;
self.slider.maximumValue = self.player.duration;
[[self player] play];
self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateSeekBar) userInfo:nil repeats:YES];
}
答案 0 :(得分:0)
如果您担心一小段延迟,那么下载并缓存 是最好的解决方案。您需要下载音频文件,然后在本地播放。通常,只有当音频非常独特且无法在本地存储时,才能从网络播放或流式传输。
实现类似这样的代码(代码未经测试):
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSFileHandle *hFile = [NSFileHandle fileHandleForWritingAtPath:self.localPath];
//did we succeed in opening the existing file?
if (!hFile) { //nope->create that file!
[[NSFileManager defaultManager] createFileAtPath:self.localPath contents:nil attributes:nil];
//try to open it again...
hFile = [NSFileHandle fileHandleForWritingAtPath:self.localPath];
}
//did we finally get an accessable file?
if (!hFile) {
NSLog("could not write to file %@", self.localPath);
return;
}
@try {
//seek to the end of the file
[hFile seekToEndOfFile];
//finally write our data to it
[hFile writeData:data];
} @catch (NSException * e) {
NSLog("exception when writing to file %@", self.localPath);
result = NO;
}
[hFile closeFile];
}
收到所有数据后,启动音频:
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.localPath error:nil];