I need to fetch frames from video located in the web. That's how I do this:
class PlayerWrapper {
private static final MediaMetadataRetriever mMediaMetadataRetriever = new MediaMetadataRetriever();
…
public void initPlayback(final Context context, final VideoSurfaceView videoSurface, final String url) {
new Thread(new Runnable() {
@Override
public void run() {
…
try {
mMediaMetadataRetriever.setDataSource(url, new HashMap<String, String>());
} catch (Exception e) {
DPLog(e);
}
}
}).start();
}
public Bitmap getFrameAt(int positionMillis) {
if (mMediaMetadataRetriever != null) {
DPLog.d("Creating frame for position [%s]", positionMillis);
try {
return mMediaMetadataRetriever.getFrameAtTime(positionMillis * 1000);
} catch (Exception e) {
…
return null;
}
} else {
return null;
}
}
}
This works fine on several devices with Android 4.4, 5 and 6. But on one device with Android 4.1.2 setDataSource
function fails with following stack trace:
java.lang.RuntimeException: setDataSource failed: status = 0xFFFFFFED
at android.media.MediaMetadataRetriever._setDataSource(MediaMetadataRetriever.java)
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:99)
at co.unreel.videoapp.playback.UnreelPlayer$3.run(UnreelPlayer.java:138)
at java.lang.Thread.run(Thread.java:856)
Also tried this code on emulator, got almost the same but with status 0x80000000
Url is got from YouTube API, looks like this:
https://r2---sn-n3toxu-axqe.googlevideo.com/videoplayback?gcr=ru&sver=3&mm=31&mn=sn-n3toxu-axqe&key=yt6&signature=D1CE7B8615F3D96A58A9D2679057D676E7777E05.5A318AD8C5F48FCED2D1A9149348CD269F466FA9&mt=1456173450&pl=24&mv=m&ms=au&lmt=1455616987173757&itag=22&requiressl=yes&ip=188.242.217.203&source=youtube&dur=848.248&id=o-ABIn_CbRwqIO6qpvlaWe_ekyTZPLVd0w_eM80awd6uRQ&fexp=9408087%2C9416126%2C9419451%2C9420452%2C9421340%2C9422596%2C9423661%2C9423662%2C9425078%2C9425963%2C9427767%2C9427801%2C9428013%2C9428432%2C9428660%2C9429602&mime=video%2Fmp4&upn=P5qxGGbPoc0&sparams=dur%2Cgcr%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cupn%2Cexpire&expire=1456195127&initcwndbps=3140000&ratebypass=yes&ipbits=0
Permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Why this can happen and what to do?
I also tried to use FFmpegMediaMetadataRetriever
with the same logic, but it doesn't work at all, setDataSource
causes exceptions with status 0xFFFFFFFF
on all devices. As I found on SO, that means that url is invalid, but it is ok and played by MediaPlayer
without any issues. Also I found that ffmpeg has issues with urls longer than 1024, but that's not my case too.
May be there are another way to get frames from video?
Get the same error. setDataSource failed: status = 0xFFFFFFED
Use Crosswalk on android to play a mp3 file on https server. And found this from google source at line 940
maybe setDataSource not support https. and this works when i use http server.