Descargar video junto con reproducción

Quiero implementar la funcionalidad de reproducción de video en línea junto con descargarla. Quiero decir, mismo flujo de descarga se debe utilizar para descargar y reproducir para que el video se puede guardar para uso sin conexión y evitar dos veces el costo de los datos para jugar y descargar por separado.

Hasta ahora he implementado la descarga de vídeo con asyncTask y lo reproduzco en OnPostExecute . El siguiente es el código:

 public class MainActivity extends AppCompatActivity { private Button btnPlay; private MediaPlayer player; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); outFilePath = getExternalFilesDir("/") + "/video.mp4"; FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); prepareVideoView(); } private VideoView videoView; String videoPath = "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_5mb.mp4"; String outFilePath = "";// private void prepareVideoView() { MediaController mediaController = new MediaController(this); videoView = (VideoView) findViewById(R.id.videoView); mediaController.setAnchorView(videoView); videoView.setMediaController(mediaController); btnPlay = (Button) findViewById(R.id.btnPlayVideo); btnPlay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new VideoDownloader().execute(videoPath); } }); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { player = mp; player.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { Log.w("download","size changed"); } }); } }); } File outFile; class VideoDownloader extends AsyncTask<String, Integer, Void> { @Override protected Void doInBackground(String... params) { outFile = new File(outFilePath); FileOutputStream out = null; BufferedInputStream input = null; try { out = new FileOutputStream(outFile,true); try { URL url = new URL(videoPath); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { throw new RuntimeException("response is not http_ok"); } int fileLength = connection.getContentLength(); input = new BufferedInputStream(connection.getInputStream()); byte data[] = new byte[2048]; long readBytes = 0; int len; boolean flag = true; int readb = 0; while ((len = input.read(data)) != -1) { out.write(data,0,len); readBytes += len; // Following commented code is to play video along with downloading but not working. /* readb += len; if(readb > 1000000) { out.flush(); playVideo(); readb = 0; } */ Log.w("download",(readBytes/1024)+"kb of "+(fileLength/1024)+"kb"); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) out.flush(); out.close(); if(input != null) input.close(); } } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); Log.w("download", "Done"); playVideo(); } } private void playVideo() { videoView.setVideoPath(outFile.getAbsolutePath()); videoView.start(); } } 

El código anterior funciona correctamente para descargar y luego reproducir. Hay alguna línea de código en el comentario en DoInBackground que traté de lograr mi objetivo, pero dice "no puedo reproducir video". ¿Alguien sabe sobre la solución? por favor, ayúdame.

Puede crear un proxy local que guarde el flujo.

Cree dos subprocesos de fondo: subproceso de descarga y subproceso de transmisión .

En el subproceso de transmisión, cree ServerSocket y los datos de flujo que se están descargando.

En el VideoView abra el URL localhost de su ServerSocket.

Necesitará manejar búferes, sincronizar hilos, etc.

Con la ayuda de Milos Fec respuesta he resuelto este problema. Tuve que crear dos hilos uno para la descarga y otro para la transmisión que el contenido descargado a través de un socketServer, mientras que el cuidado de la sincronización de los datos descargados y los datos que se están reproduciendo.

He puesto el código completo como una biblioteca en github comprobar aquí

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.