Ziad Halabi Ziad Halabi -4 years ago 127
Android Question

VideoView Playing a file while it is received via socket

I have an App that is receiving a video file from another App that is working as a Server. While the App is saving the file received on the socket, the video stream starts playing the file (which is under construction). In the code sample, after I press the btnStream, I press the btnPlay and App runs successfully. However, if the playing rate is greater than the download rate, an error will occur. I want to avoid this case. So I need to have a listener on the Video Playing that will pause the videoview when it predicts that this error will occur. I know a solution where if I know the video size, I can counter the bytes received and monitor how many seconds have been buffered and see if the videoview should pause or not. However, is it possible to do it without knowing the video file size? Or having two threads that depends on each other? Thanks.

Note: the VideoView used is a custom one where it can play FileDescriptor.

btnStream.setOnClickListener(new View.OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String s = etURL.getText().toString();
String ip = "10.0.0.24";
int port = 7878;
mct= new VideoDownloadTask(ip,port);
mct.execute();

}});
final MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(mVideoView);


Button btnPlay = (Button) findViewById(R.id.button2);
btnPlay.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
mVideoView.setVideoFD((new FileInputStream(new File("/sdcard/tempVideo.mp4")).getFD()));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mVideoView.seekTo(0);
mVideoView.start();

}
});
}

public class VideoDownloadTask extends AsyncTask<Void, Void, Void> {

String dstAddress;
int dstPort;
String response = "";
Socket socket=null;

VideoDownloadTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}

@Override
protected Void doInBackground(Void... arg0) {

try {
socket = new Socket(InetAddress.getByName(dstAddress), dstPort);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
if(socket!=null)socket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}


File f = new File("/sdcard/tempVideo.mp4");

try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DataInputStream in=null;
try {
in = new DataInputStream (socket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileOutputStream videoFile = null;
try {
videoFile = new FileOutputStream(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int len;
byte buffer[] = new byte[8192];

try {
while((len = in.read(buffer)) != -1) {
videoFile.write(buffer, 0, len);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

try {
videoFile.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return null;
}

@Override
protected void onPostExecute(Void result) {
Toast.makeText(getApplicationContext(), "Done Downloading File",
Toast.LENGTH_LONG).show();
super.onPostExecute(result);
}

}

}

Answer Source

I applied a simple solution that resolved the problem. I am sharing it if anyone is having the same problem. The solution was simply to add an error listener to the videoView that will block the error popups and pauses the video.

mVideoView.setOnErrorListener(new OnErrorListener(){
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                // TODO Auto-generated method stub
                statusText.setText("ERROR PLAYING VIDEO");
                mVideoView.pause();
                return true;
            }
        });
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download