-
Notifications
You must be signed in to change notification settings - Fork 6k
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
How to create a custom MediaSource? #5883
Comments
Thanks for doing a detailed research first. Based on your problem description, it seems you need indeed a custom There are 2 main approaches to writing a
If I understand your expected content correctly, you would eventually like to use There are also two options how this composition may look like:
Either way, you need to override the following methods:
If you want to refresh your XML from time to time to get updates, just restart the
Do you mean, you need to actually download the media data to get these updates? The usual approach would be to signal that out-of-band, e.g. through an update in your XML file. ExoPlayer does not load two streams in parallel. It only loads the next stream required for playback and then starts preloading the following stream to get smooth transitions. |
Closing, because the question was answered in detail. |
[REQUIRED] Searched documentation and issues
I've looked at a few similar questions, but none had a resolution that I feel will work for me:
Along with the issues linked above, I've check the ExoPlayer documentation on MediaSources and asked on StackOverflow. I've also experimented a bit in Android Studio, attempting to solve the problem myself through trial and error and probing the relevant objects. In this way I found that
addEventListener()
will be called, followed byprepareSource()
, and then thousands of calls are made tomaybeThrowSourceInfoRefreshError()
[REQUIRED] Question
Our company serves an XML file describing the content to be played (example: https://vcloud.blueframetech.com/api/broadcast/vmap/79999)
This XML file, among other things, gives a link to a network ID (a short 4-6 second video advertising the owner of the content), a link to the content itself (always HLS, sometimes live and sometimes archived), and a list of ad tags for playing pre-roll and mid-roll ad breaks.
We provide a web-based player and Android and iOS apps to our clients that can parse this XML file and properly play the content (example: http://njcaatv.com/landing/index).
Historically we were very hands-on with the implementation of these players. If someone wanted a custom app with their own graphics, layout, and features - we would create the app for them. If someone wanted a custom website to search through our broadcasts and play them, we would create it for them. This year we are working on converting our players into stand-alone libraries so that our clients can make their own apps and their own websites.
For the web player this is already complete. Using VideoJS we've created a single JavaScript file that can be imported into a website. You can then pass one of our XML file URLs to this player as a video source and it will download the XML, parse out all necessary information, and properly play the network ID, content, and ads.
I'm now working on the Android player, and wish to base it on ExoPlayer. To have similar ease-of-use to our web player, I had hoped to treat our XML files as a new type of media source. This way someone can simply call
.prepare(url)
and.setPlayWhenReady(true)
on a BFPlayer instance (where BFPlayer extends ExoPlayer) and it will parse out all necessary information and properly play the network ID, content, and ads.I believe the proper way to implement this in ExoPlayer is using a custom MediaSource. Just as an M3U8 contains no video data but provides links to the TS files (which do contain video data), our XML file will contain no video data but provide links (sometimes to MP4 files in the case of the network ID, sometimes to M3U8 files). Therefore this feels like it's at the same level of abstraction as the HLSMediaSource, SsMediaSource, and DashMediaSource.
If I were to build a custom MediaSource for this purpose, how would I go about it? What is expected of each method, what events do I need to fire, and how do I integrate with the DataSource and Renderer to ultimately display everything properly?
As a side note: when ads are playing, I will need to continue to download and parse the content in the background to extract metadata. This metadata is used to signal our player to perform certain actions synchronized with the content, including ending ad breaks early and resuming content. On the web player this is fairly trivial because ads are played in a separate
<video>
instance, running in an<iframe>
, overlaid on top of the content<video>
player. However when reading #3967 it was mentioned that the content and ads should share a player. In this case, is there a way to ensure that we continue to download content and monitor it for metadata?The text was updated successfully, but these errors were encountered: