2008-12-21 164 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即可。

相關問題