У меня есть приложение, которое получает видеофайл из другого приложения, работающего в качестве сервера. Пока приложение сохраняет файл, полученный в сокете, видеопоток начинает воспроизводить файл (который находится в стадии разработки). В примере кода после нажатия кнопки btnStream я нажимаю btnPlay и приложение успешно запускается. Однако, если скорость воспроизведения больше, чем скорость загрузки, произойдет ошибка. Я хочу избежать этого случая. Поэтому мне нужно иметь слушателя в видеоиграх, который приостанавливает просмотр видео, когда он предсказывает, что эта ошибка произойдет. Я знаю решение, где, если я знаю размер видео, я могу противостоять полученным байтам и контролировать, сколько секунд было буферизировано, и посмотреть, следует ли приостановить просмотр видео или нет. Однако можно ли это сделать, не зная размер видеофайла? Или имеют два потока, которые зависят друг от друга? Благодарю.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);
}
}
}