2008-12-21 132 views
17

我期待将我服务器上的一些音频文件流式传输到正在编写的iPhone客户端应用程序。即使在压缩之后,一些音频文件的大小也可能相当大。我的问题是,有没有一个Cocoa框架可以帮助我缓冲音频,使其在用户使用时可以让用户使用,而其余部分则被放在管道中?如果没有,任何人都可以指出我正确的方向来了解更多关于使用Objective-C/Cocoa来实现这样的事情所需的技术吗?将音频从服务器流式传输到iPhone

缓冲和压缩来自服务器的音频的确切资源< - >客户端基础设施将是理想的。

回答

24

Brad提到了一篇我写过的通过HTTP流式传输音频的文章。那是这一个:Streaming and playing an MP3。我不是想成为链接到他自己的博客的人,但它确实解决了你的问题。

关于问题解决的难度,您会注意到我已经对该帖子进行了4次更新(比我为其他任何操作做的更多),修复了线程错误,内存泄漏和网络缓冲的问题。有很多事情要准确无误。

+0

马特,我是你的网站的巨大粉丝。您是为确保我在阅读中保持活跃状态​​而拥有高优先级的少数选择Feed之一。非常感谢您回馈您的洞察力。 – Coocoo4Cocoa 2008-12-22 00:02:40

+0

嘿@MattGallagher,[你认为有可能以另一种方式流式传输音频](http://stackoverflow.com/questions/6166019/stream-audio-from-ios)? (从iOS设备到另一台机器?) – Moshe 2011-05-29 04:57:18

2

不幸的是,你会在你面前做一些工作。去年夏天我不得不为iPhone项目做这件事。大部分您需要的是AudioToolbox框架中的音频队列服务。

使用音频队列服务有点棘手,您将不得不实施一堆回调来告诉它如何在离开网络后处理数据包。

有人,我认为马特加拉加,有一些示例代码在博客上没关系,并且苹果的核心音频邮件列表上有一堆东西。

我确实发现我最终不需要在NSURL Connection上进行中继来完成网络部分,因为我的didrecievedata委托方法通常不够频繁。

对不起,我不能仅仅在这里写下几行代码,但是我写的这样做的代码大约有400行。

1

可以使用AVPlayer类从AVFoundation框架,从本地文件或从远程服务器流式音频。 AVPlayer类将通知您准备播放或需要缓冲更多数据。

但是,如果你想更多的控制,你应该肯定使用音频队列服务。使用音频队列服务有点困难,但一旦掌握了它,您就可以按照自己想要的方式对音频播放过程进行微调。

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

我现在知道你希望已经解决了你的问题。但只是incase。如果你想要一个直接的解决方案,你可以随时获得嵌入代码或任何其他链接,并从中创建一个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即可。

相关问题