使用AVPlayer播放时如何将音频连接到蓝牙
How to connect the audio to bluetooth when playing using AVPlayer
我正在使用 AVPlayer 从 url 播放音频,但是当 iPhone 连接到蓝牙设备时,它不是通过蓝牙播放的,如果已连接,如何通过蓝牙播放,我在 SO 中看到了一些帖子,但其中 none 得到了清楚的解释。下面是我的代码。
-(void)playselectedsong{
AVPlayer *player = [[AVPlayer alloc]initWithURL:[NSURL URLWithString:urlString]];
self.songPlayer = player;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[songPlayer currentItem]];
[self.songPlayer addObserver:self forKeyPath:@"status" options:0 context:nil];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateProgress:) userInfo:nil repeats:YES];
[self.songPlayer play];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object == songPlayer && [keyPath isEqualToString:@"status"]) {
if (songPlayer.status == AVPlayerStatusFailed) {
NSLog(@"AVPlayer Failed");
} else if (songPlayer.status == AVPlayerStatusReadyToPlay) {
NSLog(@"AVPlayerStatusReadyToPlay");
} else if (songPlayer.status == AVPlayerItemStatusUnknown) {
NSLog(@"AVPlayer Unknown");
}
}
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
// code here to play next sound file
}
您需要在 AVAudioSession
上设置类别和选项。
在应用启动时试试这个:
//configure audio session
NSError *setCategoryError = nil;
BOOL setCategorySuccess = [[AVAudioSession sharedInstance]
setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionAllowBluetooth
error:&setCategoryError];
if (setCategorySuccess) {
NSLog(@"Audio Session options set.");
} else {
NSLog(@"WARNING: Could not set audio session options.");
}
试试这个
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,
sizeof(sessionCategory),&sessionCategory);
// Set AudioSession
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:&sessionError];
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);
对于Swift3.1
简短版本:
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryRecord, with: [.allowBluetooth])
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
确保扩展版本,您使用的是正确的输入:
/**
Check availability of recording and setups audio session
with prioritized input.
*/
func setupSessionForRecording() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryRecord, with: [.allowBluetooth])
} catch {
fatalError("Error Setting Up Audio Session")
}
var inputsPriority: [(type: String, input: AVAudioSessionPortDescription?)] = [
(AVAudioSessionPortLineIn, nil),
(AVAudioSessionPortHeadsetMic, nil),
(AVAudioSessionPortBluetoothHFP, nil),
(AVAudioSessionPortUSBAudio, nil),
(AVAudioSessionPortCarAudio, nil),
(AVAudioSessionPortBuiltInMic, nil),
]
for availableInput in audioSession.availableInputs! {
guard let index = inputsPriority.index(where: { [=11=].type == availableInput.portType }) else { continue }
inputsPriority[index].input = availableInput
}
guard let input = inputsPriority.filter({ [=11=].input != nil }).first?.input else {
fatalError("No Available Ports For Recording")
}
do {
try audioSession.setPreferredInput(input)
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
}
/**
Check availability of playing audio and setups audio session
with mixing audio.
*/
func setupSessionForPlaying() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryPlayback, with: [.mixWithOthers])
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
}
主要思想是您有两个用于更改音频会话设置的函数。在录音之前使用 setupSessionForRecording
,在播放音频之前使用 setupSessionForPlaying
。
重要 使用 AVAudioSessionCategoryRecord
和 AVAudioSessionCategoryPlayback
,但不要使用 AVAudioSessionCategoryPlayAndRecord
,因为它有问题。仅当您确实需要同时播放和录制音频时才使用 AVAudioSessionCategoryPlayAndRecord
。
我正在使用 AVPlayer 从 url 播放音频,但是当 iPhone 连接到蓝牙设备时,它不是通过蓝牙播放的,如果已连接,如何通过蓝牙播放,我在 SO 中看到了一些帖子,但其中 none 得到了清楚的解释。下面是我的代码。
-(void)playselectedsong{
AVPlayer *player = [[AVPlayer alloc]initWithURL:[NSURL URLWithString:urlString]];
self.songPlayer = player;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[songPlayer currentItem]];
[self.songPlayer addObserver:self forKeyPath:@"status" options:0 context:nil];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateProgress:) userInfo:nil repeats:YES];
[self.songPlayer play];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object == songPlayer && [keyPath isEqualToString:@"status"]) {
if (songPlayer.status == AVPlayerStatusFailed) {
NSLog(@"AVPlayer Failed");
} else if (songPlayer.status == AVPlayerStatusReadyToPlay) {
NSLog(@"AVPlayerStatusReadyToPlay");
} else if (songPlayer.status == AVPlayerItemStatusUnknown) {
NSLog(@"AVPlayer Unknown");
}
}
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
// code here to play next sound file
}
您需要在 AVAudioSession
上设置类别和选项。
在应用启动时试试这个:
//configure audio session
NSError *setCategoryError = nil;
BOOL setCategorySuccess = [[AVAudioSession sharedInstance]
setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionAllowBluetooth
error:&setCategoryError];
if (setCategorySuccess) {
NSLog(@"Audio Session options set.");
} else {
NSLog(@"WARNING: Could not set audio session options.");
}
试试这个
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,
sizeof(sessionCategory),&sessionCategory);
// Set AudioSession
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:&sessionError];
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);
对于Swift3.1
简短版本:
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryRecord, with: [.allowBluetooth])
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
确保扩展版本,您使用的是正确的输入:
/**
Check availability of recording and setups audio session
with prioritized input.
*/
func setupSessionForRecording() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryRecord, with: [.allowBluetooth])
} catch {
fatalError("Error Setting Up Audio Session")
}
var inputsPriority: [(type: String, input: AVAudioSessionPortDescription?)] = [
(AVAudioSessionPortLineIn, nil),
(AVAudioSessionPortHeadsetMic, nil),
(AVAudioSessionPortBluetoothHFP, nil),
(AVAudioSessionPortUSBAudio, nil),
(AVAudioSessionPortCarAudio, nil),
(AVAudioSessionPortBuiltInMic, nil),
]
for availableInput in audioSession.availableInputs! {
guard let index = inputsPriority.index(where: { [=11=].type == availableInput.portType }) else { continue }
inputsPriority[index].input = availableInput
}
guard let input = inputsPriority.filter({ [=11=].input != nil }).first?.input else {
fatalError("No Available Ports For Recording")
}
do {
try audioSession.setPreferredInput(input)
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
}
/**
Check availability of playing audio and setups audio session
with mixing audio.
*/
func setupSessionForPlaying() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryPlayback, with: [.mixWithOthers])
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
}
主要思想是您有两个用于更改音频会话设置的函数。在录音之前使用 setupSessionForRecording
,在播放音频之前使用 setupSessionForPlaying
。
重要 使用 AVAudioSessionCategoryRecord
和 AVAudioSessionCategoryPlayback
,但不要使用 AVAudioSessionCategoryPlayAndRecord
,因为它有问题。仅当您确实需要同时播放和录制音频时才使用 AVAudioSessionCategoryPlayAndRecord
。