Подтвердить что ты не робот

Загрузите видео вместе с игрой

Я хочу реализовать функции онлайн-воспроизведения видео, а также загрузить его. Я имею в виду, что один и тот же поток загрузки должен использоваться для загрузки и воспроизведения, чтобы видео можно было сохранить для использования в автономном режиме и предотвратить вдвое большую стоимость данных для воспроизведения и загрузки отдельно.

До сих пор я реализовал загрузку видео с помощью asyncTask и воспроизвел его на OnPostExecute. Ниже приведен код:

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

Над кодом работает правильно, чтобы загрузить и затем воспроизвести. Существует некоторая строка кода в комментарии в DoInBackground, в которой я пытался достичь своей цели, но в ней говорится: "Невозможно воспроизвести видео". Кто-нибудь знает о решении? пожалуйста, помогите мне.

4b9b3361

Ответ 1

С помощью ответа Milos Fec я решил эту проблему. Мне пришлось создать два потока, один для загрузки, а другой для потоковой передачи загруженного контента через socketServer, заботясь о синхронизации загружаемых данных и воспроизводимых данных.

Я поместил весь код в виде библиотеки на github , проверьте здесь

Ответ 2

Вы можете создать локальный прокси-сервер, который сохранит поток.

Создайте два фоновых потока: поток загрузки и потоковый поток.

В потоке потокового потока создайте ServerSocket и передайте данные, которые только что загружаются.

В VideoView откройте URL-адрес localhost вашего ServerSocket.

Вам нужно будет обрабатывать буферизацию, синхронизировать потоки и т.д.