[英]iOS Audio Streaming only works for **SOME** bluetooth devices?
我正在開發iOS應用程序,它將與iOS 6/7兼容並從網站流式傳輸音頻.mp3文件。
我已經使用以下代碼將其工作:
-(NSString*)documentsFolder
{
NSString* dataPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:NULL];
return dataPath;
}
-(NSString*)createURLFile:(NSString*)songURL
{
NSString* M3U_FILE = @"song.m3u";
NSString* path = [NSString stringWithFormat:@"%@",[[self documentsFolder] stringByAppendingPathComponent:M3U_FILE]];
if([[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil])
{
NSFileHandle* outFile = [NSFileHandle fileHandleForWritingAtPath:path];
if(outFile != nil)
{
NSData* buffer = [songURL dataUsingEncoding:NSUTF8StringEncoding];
[outFile writeData:buffer];
return path;
}
}
return nil;
}
- (void)createStreamer
{
// Remove any previous references.
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Create a new player.
NSString* fileURL = [self createURLFile:self.aSong.songpath];
self.songPlayer = [[AVPlayer alloc]initWithURL:[NSURL fileURLWithPath:fileURL]];
NSAssert(self.songPlayer != nil, @"NIL AVPlayer Created!!!");
// Observer for when the song ends...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[self.songPlayer currentItem]];
[[UIApplication sharedApplication] setIdleTimerDisabled: YES];
}
我將.mp3文件的url存儲在本地.m3u文件中,並使用它來加載AVPlayer。 在早期版本的iOS中,我被告知AVPlayer會首先加載歌曲然后播放它,而不是立即播放它。 雖然這在iOS 6/7中似乎不是這樣(歌曲幾乎立即開始流式傳輸),但是正在創建.m3u文件以防萬一由於沒有以這種方式完成而產生任何問題。
有了這個,一個循環正在監視AVPlayer的狀態,幾秒鍾后,音頻開始播放手機沒有問題。
出於測試目的,我在播放歌曲的頁面上設置了一個MPVolumeView:
MPVolumeView *volumeView = [[[MPVolumeView alloc] initWithFrame:CGRectMake(0, 0, 310, 20)] autorelease];
volumeView.center = CGPointMake(160,62);
[volumeView sizeToFit];
[self.view addSubview:volumeView];
這樣做的原因是音量滑塊還會顯示一個指示燈,如果藍牙連接為音頻輸出源,並允許我更改手機和藍牙設備之間的音頻路徑。 到現在為止還挺好。
我通過藍牙將手機連接到我的Jawbox Jambone,在一首歌上啟動AVPlayer,然后歌曲按照預期從Jawbox中傳出。 音量控制有一個小的“帶箭頭的矩形”表示我可以切換音頻輸出,實際上,在播放歌曲時,我可以在手機和Jawbox之間切換。 幸福。
當我嘗試將其連接到汽車時會出現問題。 我有兩個經驗:
有人可以向我解釋為什么音頻可以流式傳輸到一個藍牙設備而不是另一個嗎?
我的應用程序配置文件中是否遺漏了某些內容(權利?),以便通過藍牙將音頻流式傳輸到汽車中?
在第一個例子中,您的汽車可能只是一個遠程玩家。 你需要注冊這樣的遠程事件(考慮使用AVAudioPlayer而不是AVPlayer)
設置AudioSession以識別藍牙音頻路由:
- (BOOL)prepareAudioSession {
// deactivate existing session
NSError *setCategoryError = nil;
NSError *activationError = nil;
BOOL success = [[AVAudioSession sharedInstance] setActive:NO error: nil];
if (!success) {
NSLog(@"deactivationError");
}
// set audio session category AVAudioSessionCategoryPlayAndRecord options AVAudioSessionCategoryOptionAllowBluetooth
success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:&setCategoryError];
if (!success)
{
NSLog(@"setCategoryError %@",setCategoryError);
}
// activate audio session
success = [[AVAudioSession sharedInstance] setActive:YES error: &activationError];
if (!success) {
NSLog(@"activationError");
}
return success;
}
你可以查看路線:
AVAudioSessionRouteDescription *mAVASRD = audioSession.currentRoute;
NSLog(@"the array is %@",mAVASRD.outputs);
for (int ctr = 0; ctr < [mAVASRD.outputs count]; ctr++)
{
AVAudioSessionPortDescription *myPortDescription = [mAVASRD.outputs objectAtIndex:ctr];
NSLog(@"the type is %@",myPortDescription.portType);
NSLog(@"the name is %@",myPortDescription.portName);
NSLog(@"the UID is %@",myPortDescription.UID);
NSLog(@"the data sources are %@",myPortDescription.dataSources);
}
然后初始化您的AVAudioPlayer並打開RemoteControlEvents(您可以使用汽車中的控制台發送播放/暫停/等)
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
然后在此堆棧溢出問題中實現類似AVAudioPlayer的委托方法,以捕獲收到的事件並在您的代碼中做出相應的反應:
在方案2中,當您將一個應用程序移動到后台(無線電流媒體應用程序)並啟動您的應用程序時,該問題的可能罪魁禍首是相同的原因 - 您的應用程序必須識別音頻的藍牙路由。
順便打電話和Siri,iOS使用不同的藍牙通道,默認為遠程控制(這是我為你的車描述的那個)。
當您設置此路線和遙控事件時,您還會獲得獎勵副產品 - 您的應用程序將可以從鎖定屏幕進行控制。 查看Apple的此技術說明,將您的應用配置為在后台播放,如果屏幕鎖定時您需要執行此操作:技術質量保證文檔QA1668
最后,為了通過您的藍牙路線增加集成,請查看MPNowPlayingInfoCenter - 將標題藝術家的作品和其他好東西放在鎖定屏幕上以及顯示該信息的汽車中的大多數藍牙屏幕上。
我很確定MPVolumeView只能解決符合較新的低功耗藍牙規格的藍牙設備......(藍牙低功耗或BLE)......
我知道手機應用程序不使用MPVolumeView,可能這個其他音頻播放器也沒有..你可能需要調查CoreBluetooth並實現自己的:(祝你好運。在github上可能有一個解決方案
設計為揚聲器的藍牙揚聲器不會有問題。
然而,汽車通常是“手機”藍牙揚聲器,並且只接受“電話”類型的通信。
我的猜測是你必須通過設置“手機音頻”連接並將傳入的音頻傳輸到空白,並將傳出的音樂流作為電話信號來欺騙它。
請注意,信號質量可能會降低,並且可能無法解決這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.