Question

I try to play video in surfaceview. I use Fragment (extends Fragment) and I have NullPointerException. I have no idea what am I doing wrong. First time I used Activity and in Activity project worked perfect but I use Fragment and I have error

This is a my source

public class Layout1 extends Fragment implements OnBufferingUpdateListener,
    OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener,
    SurfaceHolder.Callback, MediaPlayerControl {
MediaPlayer mMediaPlayer;
SurfaceView mSurfaceView;
SurfaceHolder holder;
String video = "http://www.pocketjourney.com/downloads/pj/video/famous.3gp";
MediaController mcontroller;
Handler handler;
String videoUrl;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_layout1, null);

    SurfaceView v = (SurfaceView) view
            .findViewById(R.id.screen_tutorial_video_surface);
    handler = new Handler();
    holder = v.getHolder();
    holder.addCallback(this);
    playVideo();
    return view;
}

private void playVideo() {
    try {
        mcontroller = new MediaController(getActivity());
        mcontroller.setVisibility(View.INVISIBLE);

        mMediaPlayer = MediaPlayer.create(getActivity(), Uri.parse(video));
        mMediaPlayer.setOnBufferingUpdateListener(this);
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.setOnPreparedListener(this);

        mMediaPlayer.setScreenOnWhilePlaying(true);
        mMediaPlayer.setOnVideoSizeChangedListener(this);

        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

}

@Override
public void surfaceCreated(SurfaceHolder arg0) {

    mMediaPlayer.setDisplay(holder);
    try {
        // progressDialog.dismiss();
        mMediaPlayer.start();

    } catch (IllegalStateException e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {

}

@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
    // TODO Auto-generated method stub
}

@Override
public void onPrepared(MediaPlayer mp) {

    // mcontroller.setMediaPlayer(this);
    // mcontroller
    // .setAnchorView(findViewById(R.id.screen_tutorial_video_surface));
    // mcontroller.setEnabled(true);
    //
    // handler.post(new Runnable() {
    // public void run() {
    // mcontroller.show();
    // }
    // });
}

@Override
public void onCompletion(MediaPlayer mp) {

}

@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {

}

public void start() {
    mMediaPlayer.start();
}

public void pause() {
    mMediaPlayer.pause();
}

public int getDuration() {
    return mMediaPlayer.getDuration();
}

public int getCurrentPosition() {
    return mMediaPlayer.getCurrentPosition();
}

public void seekTo(int i) {
    mMediaPlayer.seekTo(1);
}

public boolean isPlaying() {
    return mMediaPlayer.isPlaying();
}

public int getBufferPercentage() {
    return 0;
}

public boolean canPause() {
    return true;
}

public boolean canSeekBackward() {
    return true;
}

public boolean canSeekForward() {
    return true;
}
}

Error log

enter image description here

Was it helpful?

Solution

It seems that onSurfaceCreated is called before playVideo(). Initialize your mMediaPlayer (and handler too by the way) in Fragment's onCreate().

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    handler = new Handler();
    playVideo();
}

private void playVideo() {
    mcontroller = new MediaController(getActivity());
    mcontroller.setVisibility(View.INVISIBLE);

    mMediaPlayer = MediaPlayer.create(getActivity(), Uri.parse(video));
    // implement a fallback mechanism if it fails, for example if no internet or 404
    if (mMediaPlayer == null) {
        Log.w("Layout1", "Faileded to create MediaPlayer");
        return;
    }
    mMediaPlayer.setOnBufferingUpdateListener(this);
    mMediaPlayer.setOnCompletionListener(this);
    mMediaPlayer.setOnPreparedListener(this);

    mMediaPlayer.setScreenOnWhilePlaying(true);
    mMediaPlayer.setOnVideoSizeChangedListener(this);

    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_layout1, null);
    SurfaceView v = (SurfaceView) view
            .findViewById(R.id.screen_tutorial_video_surface);
    v.getHolder().addCallback(this);
    return view;
}

@Override
public void surfaceCreated(SurfaceHolder arg0) {
    if (mMediaPlayer == null) {
        // implement a fallback mechanism if it fails, for example if no internet or 404
        Log.w("Layout1", "MediaPlayer was not created");
        return;
    }
    // the holder reference is already passed as arg0 here
    mMediaPlayer.setDisplay(arg0);
    try {
        // progressDialog.dismiss();
        mMediaPlayer.start();

    } catch (IllegalStateException e) {
        e.printStackTrace();
    }
}

After you removed catch (Exception e) in playVideo()

If you looked closely in logs you could have seen

Permission failure: android.permission.INTERNET from uid=10052 pid=1129
Request requires android.permission.INTERNET
Unable to create media player
create failed:
java.io.IOException: setDataSource failed.: status=0x80000000

Thus you also need to add permission

<uses-permission android:name="android.permission.INTERNET"/>

If it wasn't for the project you've attached we would never knew.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top