2015-09-28 44 views
0

我正在通過使用TextureView在主屏幕中播放視頻,但是當我要去其他活動並留下來長時間意味着超過視頻長度並回到家庭活動,然後顯示空白視頻屏幕。當用戶重新開始活動時重新啓動視頻,它顯示MediaPlayer(15228):error(1,-2147483648)

private TextureVideoView customVideoView; 

onCreate()

customVideoView = (TextureVideoView) findViewById(R.id.customvideoview); 
String path = "android.resource://" + getPackageName() + "/"+ R.raw.home_video; 
     customVideoView.setScaleType(TextureVideoView.ScaleType.CENTER_CROP); 
     customVideoView.setDataSource(mContext, Uri.parse(path)); 
//  customVideoView.setLooping(true); 

onResume()

if(customVideoView!=null){ 
    customVideoView.play(); 
} 
customVideoView.play(); 

TextureVideoView類代碼:

public class TextureVideoView extends TextureView implements TextureView.SurfaceTextureListener { 
    Context context; 

    // Indicate if logging is on 
    public static final boolean LOG_ON = true; 

    // Log tag 
    private static final String TAG = TextureVideoView.class.getName(); 

    private MediaPlayer mMediaPlayer; 

    private float mVideoHeight; 
    private float mVideoWidth; 

    private boolean mIsDataSourceSet; 
    private boolean mIsViewAvailable; 
    private boolean mIsVideoPrepared; 
    private boolean mIsPlayCalled; 

    private ScaleType mScaleType; 
    private State mState; 

    public enum ScaleType { 
     CENTER_CROP, TOP, BOTTOM 
    } 

    public enum State { 
     UNINITIALIZED, PLAY, STOP, PAUSE, END 
    } 

    public TextureVideoView(Context context) { 
     super(context); 
     this.context=context; 
     initView(); 
    } 

    public TextureVideoView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this.context=context; 
     initView(); 
    } 

    public TextureVideoView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     this.context=context; 
     initView(); 
    } 

    private void initView() { 
     initPlayer(); 
     setScaleType(ScaleType.CENTER_CROP); 
     setSurfaceTextureListener(this); 
    } 

    public void setScaleType(ScaleType scaleType) { 
     mScaleType = scaleType; 
    } 

    private void updateTextureViewSize() { 
     float viewWidth = getWidth(); 
     float viewHeight = getHeight(); 

     float scaleX = 1.0f; 
     float scaleY = 1.0f; 

     if (mVideoWidth > viewWidth && mVideoHeight > viewHeight) { 
      scaleX = mVideoWidth/viewWidth; 
      scaleY = mVideoHeight/viewHeight; 
     } else if (mVideoWidth < viewWidth && mVideoHeight < viewHeight) { 
      scaleY = viewWidth/mVideoWidth; 
      scaleX = viewHeight/mVideoHeight; 
     } else if (viewWidth > mVideoWidth) { 
      scaleY = (viewWidth/mVideoWidth)/(viewHeight/mVideoHeight); 
     } else if (viewHeight > mVideoHeight) { 
      scaleX = (viewHeight/mVideoHeight)/(viewWidth/mVideoWidth); 
     } 

     // Calculate pivot points, in our case crop from center 
     int pivotPointX; 
     int pivotPointY; 

     switch (mScaleType) { 
      case TOP: 
       pivotPointX = 0; 
       pivotPointY = 0; 
       break; 
      case BOTTOM: 
       pivotPointX = (int) (viewWidth); 
       pivotPointY = (int) (viewHeight); 
       break; 
      case CENTER_CROP: 
       pivotPointX = (int) (viewWidth/2); 
       pivotPointY = (int) (viewHeight/2); 
       break; 
      default: 
       pivotPointX = (int) (viewWidth/2); 
       pivotPointY = (int) (viewHeight/2); 
       break; 
     } 

     Matrix matrix = new Matrix(); 
     matrix.setScale(scaleX, scaleY, pivotPointX, pivotPointY); 

     setTransform(matrix); 
    } 

    private void initPlayer() { 
     if (mMediaPlayer == null) { 
      mMediaPlayer = getMediaPlayer(context); 
      mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     } else { 
      mMediaPlayer.reset(); 
     } 
     mIsVideoPrepared = false; 
     mIsPlayCalled = false; 
     mState = State.UNINITIALIZED; 
    } 

    /** 
    * @see android.media.MediaPlayer#setDataSource(String) 
    */ 
    public void setDataSource(String path) { 
     initPlayer(); 

     try { 
      mMediaPlayer.setDataSource(path); 
      mIsDataSourceSet = true; 
      prepare(); 
     } catch (IOException e) { 
      Log.d(TAG, e.getMessage()); 
     } 
    } 

    /** 
    * @see android.media.MediaPlayer#setDataSource(android.content.Context, android.net.Uri) 
    */ 
    public void setDataSource(Context context, Uri uri) { 
     initPlayer(); 

     try { 
      mMediaPlayer.setDataSource(context, uri); 
      mMediaPlayer.setLooping(true); 
      mIsDataSourceSet = true; 
      prepare(); 
     } catch (IOException e) { 
      Log.d(TAG, e.getMessage()); 
     } 
    } 

    /** 
    * @see android.media.MediaPlayer#setDataSource(java.io.FileDescriptor) 
    */ 
    public void setDataSource(AssetFileDescriptor afd) { 
     initPlayer(); 

     try { 
      long startOffset = afd.getStartOffset(); 
      long length = afd.getLength(); 
      mMediaPlayer.setDataSource(afd.getFileDescriptor(), startOffset, length); 
      mIsDataSourceSet = true; 
      prepare(); 
     } catch (IOException e) { 
      Log.d(TAG, e.getMessage()); 
     } 
    } 

    private void prepare() { 
     try { 
      mMediaPlayer.setOnVideoSizeChangedListener(
        new MediaPlayer.OnVideoSizeChangedListener() { 
         @Override 
         public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 
          mVideoWidth = width; 
          mVideoHeight = height; 
          updateTextureViewSize(); 
         } 
        } 
      ); 
      mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
       @Override 
       public void onCompletion(MediaPlayer mp) { 
        mState = State.END; 
        log("Video has ended."); 

        if (mListener != null) { 
         mListener.onVideoEnd(); 
        } 
       } 
      }); 

      // don't forget to call MediaPlayer.prepareAsync() method when you use constructor for 
      // creating MediaPlayer 
      mMediaPlayer.prepareAsync(); 

      // Play video when the media source is ready for playback. 
      mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
       @Override 
       public void onPrepared(MediaPlayer mediaPlayer) { 
        mIsVideoPrepared = true; 
//     if (mIsPlayCalled && mIsViewAvailable) { 
         log("Player is prepared and play() was called."); 
         play(); 
//     } 

        if (mListener != null) { 
         mListener.onVideoPrepared(); 
        } 
       } 
      }); 

     } catch (IllegalArgumentException e) { 
      Log.d(TAG, e.getMessage()); 
     } catch (SecurityException e) { 
      Log.d(TAG, e.getMessage()); 
     } catch (IllegalStateException e) { 
      Log.d(TAG, e.toString()); 
     } 
    } 

    /** 
    * Play or resume video. Video will be played as soon as view is available and media player is 
    * prepared. 
    * 
    * If video is stopped or ended and play() method was called, video will start over. 
    */ 
    public void play() { 
     if (!mIsDataSourceSet) { 
      log("play() was called but data source was not set."); 
      return; 
     } 

     mIsPlayCalled = true; 

     if (!mIsVideoPrepared) { 
      log("play() was called but video is not prepared yet, waiting."); 
      return; 
     } 

     if (!mIsViewAvailable) { 
      log("play() was called but view is not available yet, waiting."); 
      return; 
     } 

     if (mState == State.PLAY) { 
      log("play() was called but video is already playing."); 
      return; 
     } 

     if (mState == State.PAUSE) { 
      log("play() was called but video is paused, resuming."); 
      mState = State.PLAY; 
      mMediaPlayer.start(); 
      return; 
     } 

     if (mState == State.END || mState == State.STOP) { 
      log("play() was called but video already ended, starting over."); 
      mState = State.PLAY; 
      mMediaPlayer.seekTo(0); 
      mMediaPlayer.start(); 
      return; 
     } 

     mState = State.PLAY; 
     mMediaPlayer.start(); 
    } 

    /** 
    * Pause video. If video is already paused, stopped or ended nothing will happen. 
    */ 
    public void pause() { 
     if (mState == State.PAUSE) { 
      log("pause() was called but video already paused."); 
      return; 
     } 

     if (mState == State.STOP) { 
      log("pause() was called but video already stopped."); 
      return; 
     } 

     if (mState == State.END) { 
      log("pause() was called but video already ended."); 
      return; 
     } 

     mState = State.PAUSE; 
     if (mMediaPlayer.isPlaying()) { 
      mMediaPlayer.pause(); 
     } 
    } 

    /** 
    * Stop video (pause and seek to beginning). If video is already stopped or ended nothing will 
    * happen. 
    */ 
    public void stop() { 
     if (mState == State.STOP) { 
      log("stop() was called but video already stopped."); 
      return; 
     } 

     if (mState == State.END) { 
      log("stop() was called but video already ended."); 
      return; 
     } 

     mState = State.STOP; 
     if (mMediaPlayer.isPlaying()) { 
      mMediaPlayer.pause(); 
      mMediaPlayer.seekTo(0); 
     } 
    } 

    /** 
    * @see android.media.MediaPlayer#setLooping(boolean) 
    */ 
    public void setLooping(boolean looping) { 
     mMediaPlayer.setLooping(looping); 
    } 

    /** 
    * @see android.media.MediaPlayer#seekTo(int) 
    */ 
    public void seekTo(int milliseconds) { 
     mMediaPlayer.seekTo(milliseconds); 
    } 

    /** 
    * @see android.media.MediaPlayer#getDuration() 
    */ 
    public int getDuration() { 
     return mMediaPlayer.getDuration(); 
    } 

    static void log(String message) { 
     if (LOG_ON) { 
      Log.d(TAG, message); 
     } 
    } 

    private MediaPlayerListener mListener; 

    /** 
    * Listener trigger 'onVideoPrepared' and `onVideoEnd` events 
    */ 
    public void setListener(MediaPlayerListener listener) { 
     mListener = listener; 
    } 

    public interface MediaPlayerListener { 

     public void onVideoPrepared(); 

     public void onVideoEnd(); 
    } 

    @Override 
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { 
     Surface surface = new Surface(surfaceTexture); 
     mMediaPlayer.setSurface(surface); 
     mIsViewAvailable = true; 
     if (mIsDataSourceSet && mIsPlayCalled && mIsVideoPrepared) { 
      log("View is available and play() was called."); 
      play(); 
     } 
    } 

    @Override 
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 

    } 

    @Override 
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 
     return false; 
    } 

    @Override 
    public void onSurfaceTextureUpdated(SurfaceTexture surface) { 

    } 

    static MediaPlayer getMediaPlayer(Context context){ 

     MediaPlayer mediaplayer = new MediaPlayer(); 

     if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) { 
      return mediaplayer; 
     } 

     try { 
      Class<?> cMediaTimeProvider = Class.forName("android.media.MediaTimeProvider"); 
      Class<?> cSubtitleController = Class.forName("android.media.SubtitleController"); 
      Class<?> iSubtitleControllerAnchor = Class.forName("android.media.SubtitleController$Anchor"); 
      Class<?> iSubtitleControllerListener = Class.forName("android.media.SubtitleController$Listener"); 

      Constructor constructor = cSubtitleController.getConstructor(new Class[]{Context.class, cMediaTimeProvider, iSubtitleControllerListener}); 

      Object subtitleInstance = constructor.newInstance(context, null, null); 

      Field f = cSubtitleController.getDeclaredField("mHandler"); 

      f.setAccessible(true); 
      try { 
       f.set(subtitleInstance, new Handler()); 
      } 
      catch (IllegalAccessException e) {return mediaplayer;} 
      finally { 
       f.setAccessible(false); 
      } 

      Method setsubtitleanchor = mediaplayer.getClass().getMethod("setSubtitleAnchor", cSubtitleController, iSubtitleControllerAnchor); 

      setsubtitleanchor.invoke(mediaplayer, subtitleInstance, null); 
      //Log.e("", "subtitle is setted :p"); 
     } catch (Exception e) {} 

     return mediaplayer; 
    } 
} 

回答

0

這是因爲你需要重新初始化TE夾具view..Do玩這個在之前的onResume方法視頻


String path = "android.resource://" + getPackageName() + "/"+ R.raw.home_video; 
    customVideoView.setScaleType(TextureVideoView.ScaleType.CENTER_CROP); 
    customVideoView.setDataSource(mContext, Uri.parse(path)); 

然後做customVideoView.play();它應該現在工作..

  1. 文件路徑出錯。
  2. 不正確的目錄或Url或Uri未找到。
  3. 媒體文件是錯誤的,不兼容的格式
  4. 缺少權限

見,這可能解決烏爾問題here is the solution

+0

還是同樣的問題 –

+0

@UjjwalKatiyar喜可您發佈的onResume方法 –

+0

@UjjwalKatiyar我編輯我的答案,你可以檢查現在:) –