Rolamix / cordova-plugin-playlist

🎶 A Cordova plugin for Android and iOS with native support for audio playlists, background support, and lock screen controls 🎶
MIT License
33 stars 33 forks source link

Fix low quality audio streaming on Bluetooth devices #10

Closed robinbanbury closed 6 years ago

robinbanbury commented 6 years ago

Description

iOS permits two Bluetooth streaming profiles: HFP and A2DP. HFP is intended for use with hands-free devices, typically when audio input from the user via a microphone is required, e.g. when speaking during a phone call. The A2DP profile is used for streaming high-quality audio to devices that support this profile, and is typically what is required by this plugin.

If both profiles are enabled in an audio session and available on the target Bluetooth device, the LOWER quality HFP profile is given priority - see the note in A2DP link below. Since there is no requirement for audio input when playing a playlist, the A2DP profile is used whenever possible; the HFP profile is only enabled for iOS versions older than 10.0, for which the A2DP profile is unavailable.

Links: https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryoptions/avaudiosessioncategoryoptionallowbluetootha2dp https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryoptions?language=objc

Related Issue

9

Motivation and Context

Bluetooth audio streaming is low quality on devices that can also be used for hands-free calling, due to an incorrect profile being enabled, which overrides the high quality output. This PR fixes that issue, by only enabling the high-quality output where available.

How Has This Been Tested?

Before change

❌ Bluetooth headphones: LOW quality playback ✅ Bluetooth speakers: HIGH quality playback ❌ Bluetooth in-car audio: LOW quality playback

After change

✅ Bluetooth headphones: HIGH quality playback ✅ Bluetooth speakers: HIGH quality playback ✅ Bluetooth in-car audio: HIGH quality playback

Types of changes

Checklist:

robinbanbury commented 6 years ago

Is it also worth enabling AirPlay? This article explains how to do that - it looks quite simple. I don't think I have any AirPlay devices to test that on, though.

I think adding a line of code like this should do it: options |= AVAudioSessionCategoryOptionAllowAirPlay

Maybe it's better to do that in another PR.

codinronan commented 6 years ago

Hey @robincsmith so the reason I didn't enable this is that supposedly it conflicts with background audio - can you check that with this change, background audio still proceeds on iOS? (e.g. wait for a song to finish while in the background, and verify that the next one plays).

codinronan commented 6 years ago

Btw yep Airplay is one of the things I'd like to do - just haven't gotten to it!

codinronan commented 6 years ago

By the way thank you so much for grabbing this bull by the horns!!!

robinbanbury commented 6 years ago

Hey @codinronan - I checked this morning using Bluetooth headphones / speaker / car audio and the background audio proceeds fine with this change applied, even switching between WiFi and 4G as the source of mobile data. Is there something that you read somewhere that suggests there would be a problem?

There is a slight stutter at the start of each track when proceeding through the playlist - about a quarter of a second of audio is played, before the track immediately restarts and continues without interruption. I'll run some tests to see if it's my change that's introduced that issue (may be next week, as I'm off on holiday tomorrow).

As for getting involved with the code - glad I can help! I've been looking for a good way to play music in the background on iOS, and there's nothing much out there at the moment for hybrid apps - iOS seems to shut down HTML5Audio no matter what I try, so it's cool to help out with something that can work in the background with streaming audio.

codinronan commented 6 years ago

@robincsmith not sure where I got that idea from! But thanks for testing - merging it in. I will check for the restart stutter - I don't think your changes would have introduced that so it might be in the sample javascript (sends the play command twice or something).

codinronan commented 6 years ago

@robincsmith I think this is the issue (from another fork): https://github.com/twogate/cordova-plugin-playlist/commit/22e473b929bb865a38cde5575d7db60b7b3bc13e

He's right, that would cause it. That scrub needs to happen when the item ends, not when it starts. Actually it already does do that when it ends, so no need to have it in both places...

https://github.com/Rolamix/cordova-plugin-playlist/blob/master/src/ios/RmxAudioPlayer.m#L721

robinbanbury commented 6 years ago

Oh, cool! Thanks for merging, and for the new 0.6.0 release.

Ah yeah.... looks like that code change on the fork might fix the stutter problem. Would be good to experiment with the change, and see if there are any other consequences of removing that line.

codinronan commented 6 years ago

I remembered why I added that line - if you play part of an item, then skip to another, when you come back to that one it will continue where it left off, not from the beginning (Which may or may not be desired behavior).

I experimented with several popular music players to see what they do, such as Spotify and iTunes, and all of them restart the song- so I made sure this one does too.. it will need a bit of checking to see what that skip you mentioned is coming from.

@robincsmith

robinbanbury commented 6 years ago

Yup, that makes sense. There must be a way to move the slider to the start of the track without affecting the playback: