3

Android 기기에서 RTSP 스트리밍을 시청하려고합니다. 그러나 서버가 스트리밍을위한 암호를 설정하면 Android가 재생할 수 없습니다. 비밀번호가 없으면 괜찮습니다. 여기 내 코드가있다.Android Media Player RTSP

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

}

내가 사용하는 IP 카메라 D-링크 DCS 942L입니다. 나는 항상 카메라에서 401 응답을 얻지 만 사용자 이름과 암호는 정확합니다. 여기에 로그가있다

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! 

내 요청 헤더가 잘못되었는지 궁금해. 그리고 내가 사용하는 것과 동일한 카메라를 사용하여 인증을 통해 RTSP를 재생하는 방법에 대한 기사는 http://www.tuicool.com/articles/R7ZF7bF입니다. 도움이나 설명에 대해 매우 감사 할 것입니다.

+0

"rtsp : // guest : [email protected] : 554/video/3gpp"를 인증 핸드 셰이크없이 시도해 보셨습니까? –

+0

@AlexCohn 예, 동일한 결과로 – dev0x10

답변

2

나는 당신처럼 RTSP 관련 코드를 개발하고 있어요, 나는 다음과 같은 결론을 발견 :

  1. MediaPlayer를 사용하는 경우, 귀하의 RTSP_URL처럼 될 수 있습니다 RTSP : // 계정 : [email protected] .x를
  2. 그러나

  3. 당신이 언급 한 인증, 카메라 사용 HTTP 기본 인증, 당신은 (내가 OKHTTP 2.0을 사용) 예 :, HTTP 요청 헤더를 추가해야하는 경우 :

    문자열 BASICAUTH = Credentials.basic을 ("account", "pass"); 요청 요청 = 새 Request.Builder(). url (url) .header ("Authorization", basicAuth) .build(); 응답 응답 = client.newCall (요청) .execute();

저에게 도움이됩니다. 희망이 당신을 위해 도움이됩니다.

+0

이미 자격증 명 (코드를 보시오) 의 헤더를 추가 하시거나 헤더를 추가하는 방법이 잘못 되었습니까? – dev0x10

+0

나는 내 자신의 헤더를 위조하여 rtsp 다이제스트 인증을 사용하여 MediaPlayer를 작동 시키려고합니다. tPacketCapture로 패킷을 캡처했기 때문에 ipcam이 200 OK로 응답했기 때문에 올바른 헤더가 있다는 것을 알고있었습니다. 하지만 setDataSource (Context, Uri, Map 와 같이 위조 된 헤더를 전달하면 (예 :'ArrayMap headers = new ArrayMap <> (1); headers.add ("Authorization", correctDigestAuth) String>), 그냥 내 사용자 정의 헤더를 전혀 보내지 않습니다 (tPacketCapture로 확인). 나머지 세션이 인증되도록 헤더를 보내는 방법이 있습니까? –