A while ago I needed to add some video playback functionality to an Android application I’m working on. I had the video files in the
assets directory of the application. I needed to figure out how to get those videos playing on the screen. This turned out to be harder than I originally expected.
The official documentation about media playback mentions that you can use the
MediaPlayer class for video and audio playback. Then it continues explaining only how to playback audio but leaves the reader with no information whatsoever how to actually do video playback.
Turns out there’s a view class called
VideoView. The documentation for that class is equally lacking. So I had to rely on my favourite search engine and go read some stackoverflow. Eventually I needed to go read the Android sources since the links I received from the search engines contained misleading information.
What I learned
So my goal was this: I want to play a video file from the
assets directory. Searching the internets got me some “answers” that either confuse assets with raw resources (the latter have resource identifiers while the former don’t – that’s a big difference) or offer code like this:
SurfaceView videoView = (SurfaceView)findViewById(R.id.myVideoView); SurfaceHolder holder = videoView.getHolder(); MediaPlayer player = new MediaPlayer(); player.setDisplay(holder);
VideoView is inherited from
SurfaceView you can technically do that. The bad news is that you really shouldn’t.
VideoView creates its own internal
MediaPlayer instance and uses that. You can’t really inject your own
MediaPlayer instance into
VideoView. This fact I only learned when I went reading the relevant source code (good that it’s open source). In my opinion this is one big omission from the Android documentation.
The code above does get your video playing on the view but none of the functionality that the
VideoView offers works (you could just use a normal
SurfaceView in this case).
If you just want to play your video from start to finish then the above code might actually suit you. But if you want to include for example some buttons for the user to control the video playback – using
MediaController perhaps – then you’ll end up into a dead end.
So, how to really do it?
The thing is, I don’t know 🙁
What I do know is this: since
VideoView uses it’s internal
MediaPlayer, the only way to set the video source is through the interface offered by
VideoView. There are methods that take either a
String (a file path) or a
Uri argument. The
MediaPlayer class would have much more choices to offer – choices that actually make it possible to load a video from the assets – which was my original intention in the first place. But that is no help here.
So, in the end I moved my video files to the
res/raw directory. This has some drawbacks but I’ll have to live with it for now.
3 replies on “Android: how (not) to play video files from assets”
Same story for me! A pity… Thanks.
Same here – stupid isn’t it?
Hey man! I’ve also recently struggled through this over a number of days. I eventually came across a third-party library over here (https://github.com/linsea/UniversalVideoView) that worked quite well, albeit with some caveats.
It seems like this is exactly why some major companies resort to coding their own proprietary solutions for playing videos.