Monday, 15 September 2014

java - Android VideoView seekTo With NodeJS API doesn't work well -



java - Android VideoView seekTo With NodeJS API doesn't work well -

i'm streaming video on videoview, phone rotation save video position , utilize seekto play video @ same moment troubles.

when set straight uri of video without using api in nodejs, seekto works perfectly:

videovvw.setvideouri(uri.parse("http://exemple.com/video.mp4"));

but when i'm using api, after 1/2 rotations dark videoview screen , error message tell me "can't play video". weird things app lot of request video api when error occur.

get /videostream?idvideo=5433f07e073a384d324bb9cf 200 105ms - 5.26mb /videostream?idvideo=5433f07e073a384d324bb9cf 200 97ms - 5.26mb /videostream?idvideo=5433f07e073a384d324bb9cf 200 98ms - 5.26mb ...

this android code:

package com.stream.activity; import java.io.unsupportedencodingexception; import com.stream.r; import android.app.activity; import android.app.progressdialog; import android.content.pm.activityinfo; import android.content.res.configuration; import android.content.res.resources.notfoundexception; import android.media.mediaplayer; import android.media.mediaplayer.onpreparedlistener; import android.media.mediaplayer.onseekcompletelistener; import android.net.uri; import android.os.asynctask; import android.os.bundle; import android.view.gravity; import android.view.view; import android.view.view.onclicklistener; import android.widget.framelayout; import android.widget.imageview; import android.widget.mediacontroller; import android.widget.toast; import android.widget.videoview; public class videoactivitynew extends activity { private videoview videovvw; private int position = 0; private mediacontroller mediacontrols; private imageview fullscreenbutton = null; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); if (getresources().getconfiguration().orientation == configuration.orientation_portrait) { setcontentview(r.layout.activity_video_portrait); videovvw = (videoview)findviewbyid(r.id.videovideoview); fullscreenbutton = new imageview(getbasecontext()); fullscreenbutton.setonclicklistener(clicklistenerchangescreensize); fullscreenbutton.setimageresource(r.drawable.full_screen_icone); } else { setcontentview(r.layout.activity_video_landscape); videovvw = (videoview)findviewbyid(r.id.videovideoview); fullscreenbutton = new imageview(getbasecontext()); fullscreenbutton.setonclicklistener(clicklistenerchangescreensize); fullscreenbutton.setimageresource(r.drawable.regular_screen_icone); } seek { streamvideo(); } grab (exception e) { toast.maketext(videoactivitynew.this, getresources().getstring(r.string.error_invalid_param), toast.length_long).show(); } } @override public void onsaveinstancestate(bundle savedinstancestate) { super.onsaveinstancestate(savedinstancestate); if (videovvw != null) { savedinstancestate.putint("position", videovvw.getcurrentposition()); videovvw.pause(); } } @override public void onrestoreinstancestate(bundle savedinstancestate) { super.onrestoreinstancestate(savedinstancestate); position = savedinstancestate.getint("position"); } private onclicklistener clicklistenerchangescreensize = new onclicklistener() { @override public void onclick(view v) { if (getresources().getconfiguration().orientation == configuration.orientation_portrait) setrequestedorientation(activityinfo.screen_orientation_landscape); else setrequestedorientation(activityinfo.screen_orientation_portrait); } }; private void streamvideo() throws notfoundexception, unsupportedencodingexception { new backgroundasynctask() .execute("http://exemple.com/videostream?idvideo=5433f07e073a384d324bb9cf"); } public class backgroundasynctask extends asynctask<string, uri, void> { progressdialog dialog; protected void onpreexecute() { dialog = new progressdialog(videoactivitynew.this); dialog.setmessage("loading, please wait..."); dialog.setcancelable(false); dialog.show(); } @override protected void onprogressupdate(final uri... uri) { seek { if (mediacontrols == null) mediacontrols = new mediacontroller(videoactivitynew.this) { @override public void setanchorview(view view) { super.setanchorview(view); framelayout.layoutparams params = new framelayout.layoutparams(layoutparams.wrap_content, layoutparams.wrap_content); params.gravity = gravity.right; addview(fullscreenbutton, params); } }; videovvw.setmediacontroller(mediacontrols); videovvw.setvideouri(uri[0]); videovvw.requestfocus(); videovvw.setonpreparedlistener(new onpreparedlistener() { @override public void onprepared(mediaplayer mp) { videovvw.seekto(position); mp.setonseekcompletelistener(new onseekcompletelistener() { @override public void onseekcomplete(mediaplayer mp) { dialog.dismiss(); videovvw.pause(); } }); } }); } grab (exception e) { e.printstacktrace(); } } @override protected void doinbackground(string... params) { seek { publishprogress(uri.parse(params[0])); } grab (exception e) { e.printstacktrace(); } homecoming null; } } }

and logcat message:

10-26 22:10:29.881: e/inputeventreceiver(1161): channel '418aab78 panel:com.test/com.test.activity.videoactivitynew (client)' ~ publisher closed input channel or error occurred. events=0x9 10-26 22:10:29.941: e/surfacetextureclient(1161): dequeuebuffer failed (no such device) 10-26 22:10:30.071: e/viewrootimpl(1161): not lock surface 10-26 22:10:30.071: e/viewrootimpl(1161): java.lang.illegalargumentexception 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.surface.lockcanvasnative(native method) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.surface.lockcanvas(surface.java:88) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.viewrootimpl.drawsoftware(viewrootimpl.java:2190) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.viewrootimpl.draw(viewrootimpl.java:2153) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.viewrootimpl.performdraw(viewrootimpl.java:2021) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.viewrootimpl.performtraversals(viewrootimpl.java:1832) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.viewrootimpl.dotraversal(viewrootimpl.java:1000) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.viewrootimpl$traversalrunnable.run(viewrootimpl.java:4214) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.choreographer$callbackrecord.run(choreographer.java:725) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.choreographer.docallbacks(choreographer.java:555) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.choreographer.doframe(choreographer.java:525) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.view.choreographer$framedisplayeventreceiver.run(choreographer.java:711) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.os.handler.handlecallback(handler.java:615) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.os.handler.dispatchmessage(handler.java:92) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.os.looper.loop(looper.java:137) 10-26 22:10:30.071: e/viewrootimpl(1161): @ android.app.activitythread.main(activitythread.java:4745) 10-26 22:10:30.071: e/viewrootimpl(1161): @ java.lang.reflect.method.invokenative(native method) 10-26 22:10:30.071: e/viewrootimpl(1161): @ java.lang.reflect.method.invoke(method.java:511) 10-26 22:10:30.071: e/viewrootimpl(1161): @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:786) 10-26 22:10:30.071: e/viewrootimpl(1161): @ com.android.internal.os.zygoteinit.main(zygoteinit.java:553) 10-26 22:10:30.071: e/viewrootimpl(1161): @ dalvik.system.nativestart.main(native method) 10-26 22:10:30.391: d/mediaplayer(1161): couldn't open file on client side, trying server side 10-26 22:10:32.501: d/mediaplayer(1161): getmetadata 10-26 22:11:05.701: e/mediaplayer(1161): error (1, -1004) 10-26 22:11:05.841: e/mediaplayer(1161): error (1,-1004) 10-26 22:11:05.841: d/videoview(1161): error: 1,-1004

in fact these errors every rotations when it's working except 3 lastly ones.

i don't if error come api or not because streaming route simple:

app.get('/videostream', function(req, res) { video.findone({_id: req.query.idvideo}, function(err, video) { if (err) console.log("err: " + err); if (video == null) console.log("video not found"); res.setheader('content-type', 'video/mp4'); fs.readfile('/home/video/video.mp4', function (err, data) { res.send(data); }); }); });

thanks help

i found answer, think problem came http header in server side:

app.get('/videostream', function(req, res) { video.findone({_id: req.query.idvideo}, function(err, video) { if (err) console.log("err: " + err); if (video == null) console.log("video not found"); res.setheader('content-type', 'video/mp4'); res.sendfile('/home/video/video.mp4', function (err) { if (err) console.log(err); }); }); });

sendfile() set header properly.

java android node.js android-mediaplayer videoview

No comments:

Post a Comment