VideoView Playing a file while it is received via socket

南楼画角 提交于 2019-12-25 03:13:43

问题


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

    }

}

回答1:


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



回答2:


pDialog = new ProgressDialog(PlayVideoActivity.this);
pDialog.setTitle("Gajacharitra");
pDialog.setMessage("Buffering video...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();

try {
    // Start the MediaController
    mediacontroller.setAnchorView(mVideoView);
    // Get the URL from String VideoURL
    Uri video = Uri.parse(mVideoURL);
    mVideoView.setMediaController(mediacontroller);
    mVideoView.setVideoURI(video);
    mVideoView.requestFocus();
    mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

        // Close the progress bar and play the video
        public void onPrepared(MediaPlayer mp) {

            pDialog.dismiss();
            mVideoView.start();
        }
    });

    mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {

        @Override
        public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {

            mVideoView.pause();
            pDialog.dismiss();
            Toast.makeText(PlayVideoActivity.this, "Can't play this video.", Toast.LENGTH_LONG).show();

            finish();
            return true;
        }
    });
} catch (Exception e) {

    /*Log.e("Error", e.getMessage());
    e.printStackTrace();*/

    pDialog.dismiss();
    Toast.makeText(PlayVideoActivity.this, "Can't play this video.", Toast.LENGTH_LONG).show();
    finish();
}


来源:https://stackoverflow.com/questions/29372319/videoview-playing-a-file-while-it-is-received-via-socket

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!