问题
I'm working on creating a custom media player using ExoPlayer (I've previously opened several questions on the same topic, because I'm very new to Android development and it seems like I run into a wall with every line of code I write).
As part of this custom player I would like to download, parse, and handle an XML file that our business produces to define our content. This XML file gives a URL for a network ID (a 4-6 second video advertising the owner of the content), a URL for the content, and an ad tag URL for playing pre-roll and mid-roll ads.
My goal is to pass this XML file as a video source to prepare()
, call setPlayWhenReady(true)
, then have everything play as expected (network ID, content, and ads)
To do this I believe I need to create a custom MediaSource -- however I cannot find any good documentation or tutorials on doing so. The ExoPlayer documentation on MediaSources is practically useless on this case, only describing how to utilize ConcatenatingMediaSource, MergingMediaSource, and LoopingMediaSource to customize the playback of media.
Update
Continuing to research on my own, it's possible what I want may be accomplished with a custom Extractor. When I pass the content to an ExtractorMediaSource I receive the error com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (MatroskaExtractor, FragmentedMp4Extractor, Mp4Extractor, Mp3Extractor, AdtsExtractor, Ac3Extractor, TsExtractor, FlvExtractor, OggExtractor, PsExtractor, WavExtractor, AmrExtractor) could read the stream.
. This makes me wonder if it's better to have an Extractor parse the XML, pull the content, and pass the data back. I'm not sure yet what the difference is between these two components or which is a better fit, and the documentation is lacking.
回答1:
Therefore the parsing of this XML file should be the responsibility of the video player, not of the client's app.
So you are essentially trying to create a new schema for distributing video for an underlying player (whatever that might be, to deal with). This seems like client side logic. However, you want an answer so I'll try and give you one.
First, Extractor
in ExoPlayer
should not be used for parsing your XML
, as per the docs:
Extracts media data from a container format.
This would be used for extracting the video data from a video container e.g. MP4.
In your scenario you probably want to look at something similar to the DashManifestParser
who uses the ParsingLoadable.Parser
whose responsibility it is to parse your input model. This ParsingLoadable.Parser
is then used by MediaSource
to get the information it needs for playback.
However, I would not recommend doing any of that. The best option for you in this scenario would be to create a Parser
to grab the content Url and just pass that to an underlying player. You content Url will link to an MP4
container, perhaps DRM'd content etc, but all of that can be handled by the player just fine without adding all of this other complexity.
As for creating adverts, this can be done in a number of ways:
- Have a single player instance, swapping between content and adverts. Easy but then you need to keep track of position information and also you will have buffering when you switch.
- Have a single player instance but use
ConcatenatingMediaSource
, for this you would parse thexml
create aMediaSource
for the content and each advert, you then add these to theConcatenatingMediaSource
. - Have a single player instance but use the
AdsLoader
provided byExoPlayer
. This is the best solution but the documentation is sadly lacking. For this you can provide a link to load adverts and a separate link to load content.
So. To summarise.
- Create a parser that can get the info you need from the XML i.e. content link and advert links.
- Create a player that creates a media source for the content and then media sources for the adverts, add these to the concatenating media source.
If you'd like to see how to do certain aspects I would suggest taking a look at our open source library that uses Exo-Player
under the hood. We've even recently started to use an AdsLoader
. https://github.com/novoda/no-player
来源:https://stackoverflow.com/questions/56115056/custom-exoplayer-mediasource-where-to-start