Android Media Player RTSP

喜欢而已 提交于 2019-12-09 06:49:39

问题


I'm trying to watch RTSP streaming on Android device. But if the server set password for the streaming my Android cannot play it. If without password it's ok. Here is my codes.

public class VideoFragment extends Fragment implements View.OnClickListener, SurfaceHolder.Callback, MediaPlayer.OnPreparedListener {


VideoView m_videoView;
SurfaceView m_surfaceView;
SurfaceHolder m_surfaceHolder;
MediaPlayer m_mediaPlayer;
SharedPreferences m_sharedPref;
Boolean m_videoStarted;

public VideoFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_video, container, false);
    m_sharedPref = this.getActivity().getSharedPreferences(MainActivity.class.getSimpleName(), Context.MODE_PRIVATE);
    m_surfaceView = (SurfaceView) view.findViewById(R.id.surfaceView);
    m_surfaceHolder = m_surfaceView.getHolder();
    m_surfaceHolder.addCallback(this);
    m_surfaceHolder.setFixedSize(320, 240);
    m_videoStarted = false;
    ToggleButton togglePlay = (ToggleButton) view.findViewById(R.id.toggleVideo);
    togglePlay.setOnClickListener(this);
    return view;
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.toggleVideo:
            if(m_videoStarted == false) {
                play();
                m_videoStarted = true;
            }
            else {
                m_mediaPlayer.reset();
            }

            break;
        default:
            Log.i(AppConfig.TAG, "DEFAULT");
            break;
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    Log.e(AppConfig.TAG, "surfaceCreated");

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    m_mediaPlayer.release();
}

@Override
public void onPrepared(MediaPlayer mp) {
    Log.e(AppConfig.TAG, "Media Player Prepared");
    m_mediaPlayer.start();
}

private void play() {
    if(m_mediaPlayer == null) {
        m_mediaPlayer = new MediaPlayer();
    }
    setErrorListener();
    m_mediaPlayer.setDisplay(m_surfaceHolder);
    m_mediaPlayer.setOnPreparedListener(this);
    try {
        Map<String, String> headers =  createHeaders();
        String videoUri = "rtsp://192.168.1.100:554/video/3gpp";
        Log.i(AppConfig.TAG, "Video URI: " + videoUri);
        m_mediaPlayer.setDataSource(getActivity(), Uri.parse(videoUri), headers);
        m_mediaPlayer.prepareAsync();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void setErrorListener() {
    m_mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            if(extra == MediaPlayer.MEDIA_ERROR_IO) {
                Log.e(AppConfig.TAG, "MEDIA ERROR");
            }
            else if(extra == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
                Log.e(AppConfig.TAG, "SERVER DIED ERROR");
            }
            else if(extra == MediaPlayer.MEDIA_ERROR_UNSUPPORTED) {
                Log.e(AppConfig.TAG, "MEDIA UNSUPPORTED");
            }
            else if(extra == MediaPlayer.MEDIA_ERROR_UNKNOWN) {
                Log.e(AppConfig.TAG, "MEDIA ERROR UNKOWN");
            }
            else if(extra == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
                Log.e(AppConfig.TAG, "NOT VALID PROGRESSIVE PLAYBACK");
            }
            else {
                Log.e(AppConfig.TAG, String.valueOf(what));
                Log.e(AppConfig.TAG, String.valueOf(extra));
                Log.e(AppConfig.TAG, "ERROR UNKNOWN!");
            }
            return false;
        }
    });
}

private Map<String, String> createHeaders() {
    String videoUri = "rtsp://192.168.1.100:554/video/3gpp";

    Map<String, String> headers =  new HashMap<String, String>();
    String camUser = "guest";//m_sharedPref.getString(AppConfig.CAM_USER,"");
    String camPassword = "tseug";//m_sharedPref.getString(AppConfig.CAM_PASSWORD,"");
    String describe = "DESCRIBE " + videoUri + " RTSP/1.0";
    String accept = "application/sdp";
    String basicAuthValue = "";

    if (camUser != "") {
        String credentials = camUser + ":" + camPassword;
        byte[] bytes = credentials.getBytes();
        int flags = Base64.URL_SAFE|Base64.NO_WRAP;
        basicAuthValue = "Basic " + Base64.encodeToString(bytes, flags);
        headers.put("Authorization", basicAuthValue);
    }

    headers.put("Request", describe);
    headers.put("Accept", accept);
    Log.i(AppConfig.TAG, "Describe: " + describe);
    Log.i(AppConfig.TAG, "Authorization: " + basicAuthValue);
    Log.i(AppConfig.TAG, "Accept: " + accept);
    return headers;
}

}

The IP Camera I use is D-link DCS 942L. I always get 401 response from the camera but my username and password is correct. Here is the log I got

    05-25 21:45:31.640   1917-19687/? W/ARTSPConnection﹕ RTSP Response: 401
05-25 21:45:31.640   1917-19687/? I/MyHandler﹕ DESCRIBE completed with result 0 (Success)
05-25 21:45:31.640   1917-19687/? E/MyHandler﹕ Server responses [401] ERROR for the DESCRIBE request
05-25 21:45:31.645   1917-19687/? W/ARTSPConnection﹕ onReceiveResponse >>> State is not CONNECTED !!!
05-25 21:45:31.665   1917-19685/? V/NuPlayer﹕ scanning sources haveAudio=0, haveVideo=0
05-25 21:45:31.665   1917-19685/? V/MediaPlayerService﹕ [152] notify (0x41c61ca0, 100, 1, -2147483648)
05-25 21:45:31.665  19534-19547/com.cameraalert.app V/MediaPlayer﹕ message received msg=100, ext1=1, ext2=-2147483648
05-25 21:45:31.665  19534-19547/com.cameraalert.app E/MediaPlayer﹕ error (1, -2147483648)
05-25 21:45:31.665  19534-19547/com.cameraalert.app V/MediaPlayer﹕ callback application
05-25 21:45:31.665  19534-19547/com.cameraalert.app V/MediaPlayer﹕ back from callback
05-25 21:45:31.665  19534-19534/com.cameraalert.app E/MediaPlayer﹕ Error (1,-2147483648)
05-25 21:45:31.665  19534-19534/com.cameraalert.app E/CameraAlert﹕ 1
05-25 21:45:31.665  19534-19534/com.cameraalert.app E/CameraAlert﹕ -2147483648
05-25 21:45:31.665  19534-19534/com.cameraalert.app E/CameraAlert﹕ ERROR UNKNOWN!

I wonder if my request header is wrong. And there's an article here http://www.tuicool.com/articles/R7ZF7bF about how to play RTSP with authentication using the same camera I use. I will be very thankful for any help or explanation.


回答1:


I'm developing the RTSP related code just like you, and I found the following conclusions:

  1. When using MediaPlayer, your RTSP_URL can be like: rtsp://account:pass@192.168.0.x
  2. But with the authentication you mentioned, if your camera use HTTP basic auth, you need to add header in http request:, ex(I use OKHTTP 2.0):

    String basicAuth = Credentials.basic("account", "pass"); Request request = new Request.Builder().url(url).header("Authorization", basicAuth).build(); Response response = client.newCall(request).execute();

That works for me! Hope it's helpful for you.



来源:https://stackoverflow.com/questions/23855965/android-media-player-rtsp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!