2015-03-31 130 views
0

我有一個應用程序從另一個作爲服務器的應用程序接收視頻文件。當應用程序保存在套接字上接收到的文件時,視頻流開始播放文件(正在建設中)。在代碼示例中,按下btnStream後,我按下btnPlay並且App成功運行。但是,如果播放速率大於下載速度,則會發生錯誤。我想避免這種情況。所以我需要在視頻播放器上有一個監聽器,當它預測會發生這個錯誤時會暫停視頻視頻。我知道一個解決方案,如果我知道視頻大小,我可以計數收到的字節數,並監視已經緩衝了多少秒,並查看視頻視圖是否應該暫停。但是,是否有可能在不知道視頻文件大小的情況下做到這一點?或者有兩個線程相互依賴?謝謝。VideoView在通過套接字接收文件時播放文件

注意:使用的VideoView是一個可以播放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

我應用了一個解決問題的簡單解決方案。如果有人遇到同樣的問題,我會分享。解決方案只是將一個錯誤偵聽器添加到videoView,這將阻止錯誤彈出窗口並暫停視頻。

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