Android - 视频在一段时间后在MediaPlayer中冻结,不会引发任何错误

时间:2015-12-31 12:33:18

标签: android audio video android-mediaplayer

为简化起见,我有一个带有两个网址的应用程序,一个用于视频文件,一个用于音频文件,并使用两个MediaPlayers播放它们,每个文件一个。

我的问题是视频在1-3秒后冻结(每次更改),同时音频继续正常。 我没有从MediaPlayer那里得到任何错误或例外,我甚至试图取消音频媒体播放器而只留下视频(因为我虽然是赛车问题),但它仍然有相同的行为。

以下是相关的代码段:

    audioPlayer = new MediaPlayer(); // both media players declared outside
    audioPlayer.setOnPreparedListener(this);
    audioPlayer.setOnCompletionListener(this);
    audioPlayer.setOnErrorListener(this);
    audioPlayer.setScreenOnWhilePlaying(true);

    videoPlayer = new MediaPlayer();
    videoPlayer.setOnPreparedListener(this);
    videoPlayer.setOnCompletionListener(this);
    videoPlayer.setOnErrorListener(this);
    videoPlayer.setScreenOnWhilePlaying(true);

    try {
        audioPlayer.setDataSource(audioPath);
        Log.d(LOG_TAG, "audioPlayer.setDataSource(" + audioPath + ")");
        videoPlayer.setDataSource(videoPath);
        Log.d(LOG_TAG, "videoPlayer.setDataSource(" + videoPath + ")");
    } catch (Exception e) {
        Log.e(LOG_TAG, "setDataSource() - " + e.getMessage());
        return;
    }

    try {
        audioPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        float volume = Float.valueOf(options.getString("volume"));
        Log.d(LOG_TAG, "setVolume: " + volume);
        audioPlayer.setVolume(volume, volume);
    } catch (Exception e) {
        Log.e(LOG_TAG, "setVolume() - " + e.getMessage());
        return;
    }

    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
        try {
            int scalingMode = options.getInt("scalingMode");
            switch (scalingMode) {
            case MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING:
                videoPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
                Log.d(LOG_TAG, "setVideoScalingMode VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING");
                break;
            default:
                videoPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);
                Log.d(LOG_TAG, "setVideoScalingMode VIDEO_SCALING_MODE_SCALE_TO_FIT");
            }
        } catch (Exception e) {
            Log.e(LOG_TAG, "setVideoScalingMode() - " + e.getMessage());
        }
    }

    final SurfaceHolder mHolder = videoView.getHolder(); //videoview is another view in the display, but it does nothing
    mHolder.setKeepScreenOn(true);
    mHolder.addCallback(new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            Log.d(LOG_TAG, "Surface Created");

            videoPlayer.setDisplay(holder);
            try {
                videoPlayer.prepareAsync();
                audioPlayer.prepareAsync();
                Log.d(LOG_TAG, "prepare()");
            } catch (Exception e) {
                Log.e(LOG_TAG, "prepare() - " + e.getMessage());
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.d(LOG_TAG, "Surface Destroyed");

            try {
                audioPlayer.release();
            }
            catch(Exception e) {
                // already released
            }
            try {
                videoPlayer.release();
            }
            catch(Exception e) {
                // already released
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            Log.d(LOG_TAG, "Surface Changed");
        }
    });

@Override
public void onPrepared(MediaPlayer mp) {
    Log.i(LOG_TAG, "MediaPlayer prepared");

    if (mp.equals(videoPlayer)) {
         mp.setWakeMode(cordova.getActivity(), PowerManager.PARTIAL_WAKE_LOCK);
         mp.start();
         mp.seekTo(0);
    }

    mp.start();
}

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
    Log.e(LOG_TAG, "MediaPlayer.onError(" + what + ", " + extra + ")");

    if (what == 100) { //reached end of stream, it's not really an error
        this.onCompletion(mp);
    }

    if(mp != null && mp.isPlaying()) {
        mp.stop();
    }

    if (mp != null) {
        mp.setDisplay(null);
        mp.release();
    }

    return false;
}

@Override
public void onCompletion(MediaPlayer mp) {
    Log.i(LOG_TAG, "MediaPlayer completed");

    try {
        videoPlayer.setDisplay(null);
        videoPlayer.release();
    }
    catch (Exception ex) {
        // already released
    }

    try {
        audioPlayer.release();
    }
    catch (Exception ex) {
        // already released
    }
}

有人知道为什么吗? 感谢。

修改

我注意到对于videoPlayer我收到701 \ 702的许多警告。也许这有关系?它似乎一直在缓冲数据,但从未恢复过来。

0 个答案:

没有答案