Android SurfaceView: Show Video after Images -
i want play video after couple of images in same surfaceview. if show images after videos, works fine. if want play video after images, surfaceview stays blank (black). can help? seems problem of clearing or resetting surfaceview!
the code of surfaceview (custom surfaceview!!!):
public class mysurfaceview extends surfaceview implements surfaceholder.callback, mediaplayer.oncompletionlistener { private bitmap image; private mediaplayer mediaplayer; private list<mysurfacelistener> objectstocall = new arraylist<>(); public mysurfaceview(context context) { super(context); getholder().addcallback(this); } public void addonplayingfinishedlistener(mysurfacelistener listener) { objectstocall.add(listener); } public void notifyallonplayingfinishedlistener() { for(mysurfacelistener l : objectstocall) { l.onmediaplayfinished(); } } public static int calculateinsamplesize(bitmapfactory.options options, int reqwidth, int reqheight) { // helper method scale down image files } public static bitmap decodesampledbitmapfromfile(string path, int reqwidth, int reqheight) { // helper method image files } public void drawimage(string path, final int durationms) { this.image = decodesampledbitmapfromfile(path, 1920, 1080); canvas canvas = null; try { canvas = getholder().lockcanvas(null); synchronized (getholder()) { ondraw(canvas); } } catch (exception e) { e.printstacktrace(); } { if (canvas != null) { getholder().unlockcanvasandpost(canvas); } image.recycle(); image = null; } thread showpicturetimer = new thread(new runnable() { @override public void run() { try { thread.sleep(durationms); } catch (interruptedexception e) { e.printstacktrace(); } } }); showpicturetimer.start(); try { showpicturetimer.join(); } catch (interruptedexception e) { e.printstacktrace(); } notifyallonplayingfinishedlistener(); } public void playvideo(string path) { try { mediaplayer = new mediaplayer(); mediaplayer.setoncompletionlistener(this); mediaplayer.setdisplay(getholder()); mediaplayer.setdatasource(path); mediaplayer.prepare(); mediaplayer.start(); } catch (illegalargumentexception e) { log.d("mymediaplayercontrol", e.getmessage()); } catch (illegalstateexception e) { log.d("mymediaplayercontrol", e.getmessage()); } catch (ioexception e) { log.d("mymediaplayercontrol", e.getmessage()); } } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); canvas.drawcolor(color.black); canvas.drawbitmap(this.image, 0, 0, new paint()); } public void surfacechanged(surfaceholder arg0, int arg1, int arg2, int arg3) { log.e("myapp", "surfacechanged"); } public void surfacecreated(surfaceholder arg0) { log.e("myapp", "surfacecreated"); } public void surfacedestroyed(surfaceholder arg0) { log.e("myapp", "surfacedestroyed"); } @override public void oncompletion(mediaplayer mp) { if (mediaplayer != null) { mediaplayer.stop(); mediaplayer.release(); mediaplayer = null; } notifyallonplayingfinishedlistener(); } }
and thread gives file paths surface view playing (should not problem):
public class mediacontrolthread extends thread implements mysurfacelistener { public static list<string> medialist = new arraylist<string>(); mymediaactivity activity; private mysurfaceview surfaceview; private int currentvideo = 0; public mediacontrolthread(mymediaactivity activity) { this.activity = activity; this.surfaceview = activity.getsurfaceview(); this.surfaceview.addonplayingfinishedlistener(this); } @override public void run() { try { while(medialist.size() == 0) { thread.sleep(1000); } thread.sleep(3000); } catch (interruptedexception e) { e.printstacktrace(); } playmedia(medialist.get(currentvideo)); } private void playmedia(string mediapath) { if(checkfileforimage(mediapath)) { surfaceview.drawimage(mediapath, 2000); } else { surfaceview.playvideo(mediapath); } } private boolean checkfileforimage(string filename) { string file = filename.tolowercase(); return file.endswith(".jpg") || file.endswith(".img") || file.endswith(".bmp") || file.endswith(".jpeg") || file.endswith(".ico") || file.endswith(".tif"); } @override public void onmediaplayfinished() { surfaceview.invalidate(); surfaceview.destroydrawingcache(); currentvideo++; if (currentvideo > medialist.size() - 1) { currentvideo = 0; } playmedia(medialist.get(currentvideo)); } }
that is, unfortunately, expected behavior. due quirk in android, once you've drawn on surface canvas can't else.
you have 3 choices:
- draw image opengl es rather canvas. once detach gles can go showing videos.
- present image single-frame video. works nicely trivial things blanking screen, poor choice dynamic content.
- use framelayout overlay imageview or custom view. show view when want show image, hide otherwise. long surface @ default z-depth, imageview appear in front of , obscure it.
Comments
Post a Comment