прогрессивная загрузка видео с помощью медиаплеера Android

Я работаю над потоковой передачей видео по сетям с задержкой, используя мобильные телефоны Android. Для этого я пытаюсь реализовать прогрессивную загрузку видео на основе учебника, предоставленного pocket travel

http://blog.infidian.com/2008/04/04/tutorial-custom-media-streaming-for-androids-mediaplayer/

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

Я использую SurfaceView и SUrfaceHolder для отображения видео, как это предлагается в демонстрационных материалах API.

private MediaPlayer createMediaPlayer(File mediaFile)
throws IOException {
    MediaPlayer mPlayer = new MediaPlayer();
    mPlayer.setOnErrorListener(
            new MediaPlayer.OnErrorListener() {
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    Log.e(TAG, "Error in MediaPlayer: (" + what +") with extra (" +extra +")" );
                    return true;
                }
            });

    //  It appears that for security/permission reasons, it is better to pass a FileDescriptor rather than a direct path to the File.
    //  Also I have seen errors such as "PVMFErrNotSupported" and "Prepare failed.: status=0x1" if a file path String is passed to
    //  setDataSource().  So unless otherwise noted, we use a FileDescriptor here.
    FileInputStream fis = new FileInputStream(mediaFile);
    mPlayer.setDataSource(fis.getFD());
    mPlayer.setDisplay(holder);
    mPlayer.prepareAsync();
    return mPlayer;
}

/**
 * Transfer buffered data to the MediaPlayer.
 * NOTE: Interacting with a MediaPlayer on a non-main UI thread can cause thread-lock and crashes so 
 * this method should always be called using a Handler.
 */  
private void transferBufferToMediaPlayer() {
    try {
        // First determine if we need to restart the player after transferring data...e.g. perhaps the user pressed pause
        final boolean wasPlaying = mediaPlayer.isPlaying();
        final int curPosition = mediaPlayer.getCurrentPosition();
        Log.e(TAG, "Current position: "+curPosition);
        final MediaPlayer temp = mediaPlayer;

        // Copy the currently downloaded content to a new buffered File.  Store the old File for deleting later. 
        File oldBufferedFile = new File(context.getCacheDir(),"playingMedia" + counter + ".dat");
        File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");

        //  This may be the last buffered File so ask that it be delete on exit.  If it's already deleted, then this won't mean anything.  If you want to 
        // keep and track fully downloaded files for later use, write caching code and please send me a copy.
        bufferedFile.deleteOnExit();   
        moveFile(downloadingMediaFile,bufferedFile);

        // Pause the current player now as we are about to create and start a new one.  So far (Android v1.5),
        // this always happens so quickly that the user never realized we've stopped the player and started a new one
        if(wasPlaying){
            Log.e(TAG, "mediaPlayer paused");
            mediaPlayer.pause();
        }
        //mediaPlayer.release();

        // Create a new MediaPlayer rather than try to re-prepare the prior one.
        mediaPlayer = createMediaPlayer(bufferedFile);

        mediaPlayer.setOnPreparedListener(
                new MediaPlayer.OnPreparedListener() {

                    @Override
                    public void onPrepared(MediaPlayer mPlayer) {
                        // TODO Auto-generated method stub
                        mediaPlayer.seekTo(curPosition);

                        //  Restart if at end of prior buffered content or mediaPlayer was previously playing.  
                        //  NOTE:  We test for < 1second of data because the media player can stop when there is still
                        //  a few milliseconds of data left to play
                        int mediaLength = mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition();
                        boolean atEndOfFile = mediaLength >= 1000;
                        Log.e(TAG, "MediaLen:"+mediaLength);
                        if (wasPlaying || atEndOfFile){
                            Log.e(TAG, "starting new player");
                            temp.release();
                            mediaPlayer.start();
                        }
                    }
                });


        // Lastly delete the previously playing buffered File as it's no longer needed.
        oldBufferedFile.delete();

    }catch (Exception e) {
        Log.e(TAG, "Error updating to newly loaded content.", e);                   
    }
}

person user1466411    schedule 19.06.2012    source источник


Ответы (1)


Рассмотрите возможность использования exoplayer

http://developer.android.com/guide/topics/media/exoplayer.html

он был построен с учетом потоковой передачи из документации:

ExoPlayer поддерживает функции, которые в настоящее время не предоставляются MediaPlayer, включая динамическую адаптивную потоковую передачу по HTTP (DASH), SmoothStreaming и постоянное кэширование. ExoPlayer может быть расширен для обработки дополнительных форматов мультимедиа, и, поскольку вы включаете его как часть кода приложения, вы можете обновлять его вместе со своим приложением.

person karel.herink    schedule 25.04.2015