Categories
Android

Android: how (not) to play video files from assets

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);

Since VideoView is inherited from SurfaceView you can technically do that. The bad news is that you really shouldn’t.

That’s because 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”

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.

Leave a Reply to Jamie Cancel reply

Your email address will not be published.