Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Android Auto Support #2094

Open
wants to merge 84 commits into
base: main
Choose a base branch
from

Conversation

lovegaoshi
Copy link
Contributor

continuation of #2043 . Synced up with RNTP v4.0.0 rc07

lovegaoshi and others added 30 commits June 15, 2023 06:20
feat: full android auto support
@andreknieriem
Copy link

Hi @lovegaoshi . I've maybe found a bug. There is no "subtitle"/artists on my headunit. I've tried the default artist for trackplayer and a subtitle too. But none of them is showing up. Any advice?

@lovegaoshi
Copy link
Contributor Author

i dont think RNTP track has a subtitle property - u could try mapping all artist to subtitle and see if that works

@andreknieriem
Copy link

i dont think RNTP track has a subtitle property - u could try mapping all artist to subtitle and see if that works

So you don't have a subtitle too in your android auto headunit?

image

Here I am missing Linkin Park as artist. In my list views it is showing up:
image

Of course I tried to set subtitle on my now playing item but it doesn't work. Any idea?

@lovegaoshi
Copy link
Contributor Author

how exactly did u map/use subtitle?
eg if u map artist to subtitle like this lovegaoshi/KotlinAudio@aefe6d8
it would work:
image
which works the same if u set the mediaItem's subtitle as well

@andreknieriem
Copy link

Thanks for your answer, but I don't get it.
I have a playlist like this with 1 track for example

[
  {
    id: 11,
    title: "More the victim"
    subtitle: "Linkin Park",
    artist: "Linkin Park",
    url: "https://url.com/lp.mp3",
    duration: 200,
    artwork: "cover.jpg"
  }
]

This works all in my app on my phone with trackplayer. It shows everywhere in the notification and so on. On my android auto it doesn't show the artist. You see I tried setting both artist and subtitle, but that didn't change anything. Now I tried your latest version with implementation 'com.github.lovegaoshi:KotlinAudio:v2.0.0-aa23' as dependency but it says, that there is no version aa23 in jitpack.io.

@lovegaoshi
Copy link
Contributor Author

lovegaoshi commented May 17, 2024 via email

@KestasVenslauskas
Copy link

Wanted to try this out but can't get past this error:
Failed to resolve: com.github.lovegaoshi:KotlinAudio:v2.0.0-aa23

@lovegaoshi
Copy link
Contributor Author

can u not build? bc i can
image
or ur network/jitpack is not stable rn

@KestasVenslauskas
Copy link

can u not build? bc i can image or ur network/jitpack is not stable rn

Yes it was just an issue with jitpack being down probably. Now it works

@lovegaoshi
Copy link
Contributor Author

lovegaoshi commented May 29, 2024

edit about album art on AA:

I originally enabled album art via lovegaoshi/KotlinAudio@7a3d90b but google's guidelines seem to contradict with that. nevertheless however RNTP is currently set up (for ex https://github.com/lovegaoshi/react-native-track-player/blob/6f634594f24aa1974b2c8cdc6848b8b349cccdf0/android/src/main/java/com/doublesymmetry/kotlinaudio/notification/NotificationManager.kt#L389) for remote urls it works great, but for local uris (file:///) and embedded covers within local media files it wont work.

for local uris while I do not have a use and no rigorous tests yet, I believe converting the file:/// uri to a content:// one, as specified in the google guidelines, would work. u can see how i did this via a fileProvider: lovegaoshi/azusa-player-mobile#449

for embedded covers (which I worked on for the past few days) this has to be first resolved and written to a file, then load the content:// uri as in the google guidelines. I tried with both ffmpeg and MediaMetadataRetriever, opted for the latter in the end for simplicity. commit is here: lovegaoshi@6f63459

the specific implementation I have does have a drawback taht the local file is written in the /Pictures folder. you might be able to write to cache using File() then convert to content:// with a fileProvider, but I chose the simplicity of MediaStore and can deal with this drawback.

@syedslegend786
Copy link

I'm utilizing react-native-track-player for my player implementation in a React Native app. While attempting to fetch local artwork stored at "file:///data/user/0/au.com.podcastoneaustralia.dev/files/offline/c95fee2d-5099-4ace-8c86-b00500231c2e/imageUrl.jpg", I encounter an issue where the artwork fails to load within the list and player components. Strangely, it displays perfectly fine for the queue list in Android Auto.

My understanding is the iconUri string gets mapped to the mediaDescriptionBuilder.iconUri which is used to populate the MediaItem that we see on the Android Auto screen, so in theory it should be working for any local file Uri that gets saved to a device (i.e a downloaded piece of content + image that is saved to local storage).

I'm seeking assistance to resolve this inconsistency and ensure that the local artwork loads seamlessly across all components, including the list and player interfaces within the Android Auto app.

  1. media List : AndroidAutoBrowseTree
Screenshot 2024-03-28 at 3 39 17 pm 2. Player View Screenshot 2024-03-28 at 3 39 27 pm 3. queue list: where we used ** TrackPlayer.add** it accept the require("file path") Screenshot 2024-03-28 at 3 39 36 pm

Hi could you plz share any example project , that using RNTP working fine on android auto

@Ali-ch88
Copy link

Ali-ch88 commented Jun 5, 2024

@lovegaoshi @PatelPiyush04 @andreknieriem I need some guidelines regarding RNTP with Android Auto.
Currently, we're working on the React Native application in which we have implemented the React Native track player, now our goal is to connect our app with the Android Auto. So, need to confirmation that RNTP is working properly with Android Auto or not?

@lovegaoshi
Copy link
Contributor Author

lovegaoshi commented Jun 5, 2024 via email

@KestasVenslauskas
Copy link

KestasVenslauskas commented Jun 20, 2024

Is A-Z sorting be implemented here? Not sure how is this done on spotify
Example:
Screenshot at Jun 20 13-20-04

@lovegaoshi
Copy link
Contributor Author

lovegaoshi commented Jun 20, 2024 via email

@MatejMijic
Copy link

Hey @lovegaoshi, awesome work. I was able to implement your solution and was wondering if there is possibility to show progress indicator while items are loading? Currently Android Auto just shows message "No items". Can you give me some advice/directions on how could I extend this solution to support it?

@lovegaoshi
Copy link
Contributor Author

lovegaoshi commented Jul 4, 2024 via email

@caustin24345
Copy link

@MatejMijic - You can force a loading indicator by explicitly returning null from the onLoadChildren callback. My implementation pushes a media item with a specific mediaId while content is being fetched. When the onLoadChildren callback is fired, you can check to see what the mediaId of the pushed media item is, and return null if needed. Once the data is fetched, a new media item can be pushed to the tree which includes the loaded content.

@lovegaoshi - I am wondering if you have any ideas about react-native >= 0.73, with the new bridgeless architecture. I can see that the app works as expected with AA minus headless mode. I am going to have a look into exactly what is happening, but thought I would see if you had any ideas / intention to upgrade your app to later versions of react-native. I noted that you have mentioned that this will be difficult to maintain moving forwards, and so I'm wondering if it is better to handle AA completely natively if launched headlessly.

@lovegaoshi
Copy link
Contributor Author

lovegaoshi commented Jul 29, 2024 via email

@caustin24345
Copy link

@lovegaoshi - Thanks, I've had a look at those issues in the RN repo. I can see that it looks like RN will deprecate headlessJS and leave it up to 3rd party packages for their own integration. When you say without bridgeless, everything works flawlessly on 0.74.3, do you mean that you have enabled the new arch but have set bridgeless = false in the load function, or do you mean without the new arch entirely (and therefore without bridgeless).

I will likely look into migrating to an entirely native approach for AA to futureproof the functionality for any RN or Expo changes in the future. The implemetation seems very fragile at the moment with all of these new architectural changes. Thanks again for your help.

@lovegaoshi
Copy link
Contributor Author

lovegaoshi commented Jul 29, 2024 via email

@lovegaoshi
Copy link
Contributor Author

while working with my media3 migration work, I found I could not reliably wake up activities anymore via MediaLibrarySession.Callback, as legacy controller package names are handled there. However I found something interesting that the service actually launches the JS bridge. setupPlayer is blocked by MusicModule but I maybe have a better understanding about the error and believe this is no longer the case..? So if one invokes setupPlayer inside index.js you will have a fully functional service with event emitters/parsers.

This requires some proof of concept work and probably major refactors for a lot of us but great if can be done. I dont remember the JS bridge actually initializes with exoplayer2 but its been a while.

@lovegaoshi
Copy link
Contributor Author

update:
turns out i discovered this by accident. bc I configured something wrongly and my terminated service keeps calling onStartCommand, I accidentally discovered the JS bridge actually initializes along with service (I presume the reactContext is initialized somewhere), as onStartCommand registers headlessTaskService. So the solution is quite clear:

  1. at where I used to wake up the activity, invoke onStartCommand instead.
  2. move all player setup out of any view and put it directly in the app entrypoint (index.js).
  3. remove the "android_cannot_setup_player_in_background" restriction in MusicModule.

You may reference my media3 migration work that I believe showcases the headless start. You should see the mediaSession loads, along with the headlessJS events emit even if the app is fully closed, while being awaken by say the media controller tester.

While I'm having many issues with media3 right now, i dont see myself maintaining this fork anymore once I get media3 to work to the bare minimum. PR will be left open as i think its mostly functional, until the maintainers decide to migrate to media3 as well.

@Vashiru
Copy link

Vashiru commented Dec 18, 2024

@lovegaoshi Thanks for all your work. I'm looking to integrate Android Auto into an app of my own. Quickly reading through this PR, I see a lot of mentions of media2 and media3. Am I correct that despite the fact that media2 is deprecated, this should still be a fully functional example?

All I really need is for it to play a shoutcast stream. Some direct urls to MP3s in the future to add podcasts would be nice, but first and foremost would be the shoutcast stream. I've poked react-native-carplay (which has experimental Android Auto support, but lacks some documentation in that department) and react-native-android-auto (which was build in a hackathon and doesn't seem to be as plug-n-play as it appears on the surface), but couldn't get those to work. So hoping just using your extension to RNTP does the trick.

@lovegaoshi
Copy link
Contributor Author

lovegaoshi commented Dec 18, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.