首页 文章

使用Android媒体播放器的渐进式视频下载

提问于
浏览
3

我正在使用Android手机在延迟容忍网络上进行视频流传输 . 为此我试图实现基于口袋旅程给出的教程的渐进式视频下载

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

1 回答

  • 0

    考虑使用exoplayer

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

    它是根据文档中的流媒体构建的:

    ExoPlayer支持MediaPlayer当前未提供的功能,包括HTTP上的动态自适应流(DASH),SmoothStreaming和持久缓存 . ExoPlayer可以扩展为处理其他媒体格式,因为您将其作为应用代码的一部分包含在内,您可以将其与应用一起更新 .

相关问题