我正在寻找将我服务器上的一些音频文件流式传输到我正在编写的iPhone客户端应用程序。即使在压缩之后,一些音频文件的大小也可能相当大。我的问题是,是否有一个Cocoa框架可以帮助我缓冲音频,以便用户可以使用它而其余部分被放下管道?如果没有,有人能指出我正确的方向,以了解更多关于使用Objective-C / Cocoa实现此类事情所需的技术吗?
从服务器< - >客户端基础设施缓冲和压缩音频的权威资源将是理想的。
答案 0 :(得分:24)
Brad提到了我写的一篇帖子,用于通过HTTP传输音频。就是这个:Streaming and playing an MP3。我并不是指那些链接到他自己的博客的人,但它确实解决了你的问题。
关于解决问题的难度,您会注意到我已经对该帖子进行了4次更新(比其他任何方式都做得更多),修复了线程错误,内存泄漏和网络缓冲问题。有很多东西要准确无误。
答案 1 :(得分:5)
MPMoviePlayerController可以播放音频文件。如果使用内容URL初始化对象(例如,这可以是服务器上的Mp3文件),它将流式传输文件并进行播放。
初始化如下所示:
NSURL *theURL = [NSURL urlWithString:@"http://yourdomain.com/yourmediafile.mp3"];
MPMoviePlayerController* yourPlayerController = [[MPMoviePlayerController alloc] initWithContentURL:theURL];
从那里你可以弹出一个回放视图,它将显示一个用于擦除内容的滑块,它将填充滑块作为内容缓冲区。
[yourPlayerController shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeRight];
[self presentMoviePlayerViewControllerAnimated:yourPlayerController];
或者您可以让它播放并创建自己的UI:
[yourPlayerController.moviePlayer play];
这种播放方法会在屏幕锁定时切断音频,除非您告诉应用程序在info.plist文件的后台运行。
答案 2 :(得分:2)
不幸的是,你会在你面前做一些工作。去年夏天,我不得不为iPhone项目做这件事。您需要的大部分内容都在AudioToolbox框架中的音频队列服务中。
使用音频队列服务有点棘手,你必须实现一堆回调来告诉它如何在数据包离开网络后对其进行处理。
有人,我认为Matt Gallagar在博客上有一些示例代码没问题,Apple的Core Audio Mailing List上有很多东西。
我确实发现我最终不需要在NSURL Connection上进行中继来执行网络部分,因为我的didrecievedata委托方法没有经常触发。
很抱歉,我不能在这里输入几行代码作为例子,但我写的这个类大约有400行。
答案 3 :(得分:2)
我现在知道你希望已经解决了你的问题。但只是因为。如果你想要一个直接的解决方案,你总是可以得到嵌入代码或任何其他链接,并从中制作一个html文件。像
<html>
<body>
<script type="text/javascript">
var embedBaseUrl = 'http://www.tv.net/';
var embedChannelId = 13;
var embedSize = [300,250];
var embedAutoplay = true;
</script>
<script type="text/javascript"src="http://www.tv.net/assets/js/embed.js"></script>
</body>
</HTML>
ViewController.h
@interface ViewController : UIViewController {
NSString *videoURL;
}
@property (nonatomic, strong) NSString *videoURL;
(IBAction) tv;
在ViewController.m中
@synthesize videoURL;
(IBAction) tv {
self.videoURL = @"http://dl.dropbox.com/x/xxxxxxxx/HTML/tv.html";
VideoViewController *videoViewController = [[VideoViewController alloc] initWithNibName:nil bundle:nil];
videoViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; videoViewController.videoURL = self.videoURL;
[self presentViewController:videoViewController animated:YES completion:nil]; }
然后在VideoViewController.h中
IBOutlet UIWebView *videoView;
NSString *videoURL; NSString *videoHTML;
}
@property(nonatomic, retain) IBOutlet UIWebView *videoView; @property(nonatomic, retain) NSString *videoURL; @property(nonatomic, retain) NSString *videoHTML;
(void) embedTV;
VideoViewController.m
@synthesize videoView, videoURL, videoHTML;
(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; }
(void)embedTV {
videoHTML = [NSString stringWithFormat:@"\ \ \ \ iframe {position:absolute; top:50%%; margin-top:-130px;}\ body {background-color:#000; margin:0;}\ \ \ \ \ \ ", videoURL];
[videoView loadHTMLString:videoHTML baseURL:nil]; }
(void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib.
videoView.backgroundColor = [UIColor blackColor]; videoView.opaque = NO;
[self embedTV]; }
现在在我的例子中我引用了视频流,但是你明白了,你可以流式传输或播放你想要的内容。只需使用UIWebView
。
答案 4 :(得分:1)
您可以使用AVFoundation框架中的 AVPlayer 类从本地文件或远程服务器流式传输音频。 AVPlayer类将通知您播放的准备情况或缓冲更多数据的需要。
但是,如果您想要更多控制权,则一定要使用音频队列服务。使用音频队列服务有点困难,但是一旦你掌握了它,你就能够按照你想要的方式微调音频播放过程。