2012-05-23 3 views
6

로컬 Socket을 통해 Android의 MediaRecorder에서 h264/AAC 비디오를 보내려고합니다. 목표는 RTMP 또는 RTSP를 통해 WOWZA 서버로 비디오를 보내는 것이지만, 많은 문제를 일으키고 있습니다. 지금은 LocalServerSocket에서 파일에 데이터를 쓰려고합니다.LocalSocket을 통한 MediaRecorder의 비디오 스트리밍

다음은 몇 가지 코드입니다. 미안하지만, 정말 깨끗한 아니에요,하지만 시간을 보냈다 많은 ​​것들을 테스트하고 내 프로젝트는 지금 엉망이다. 카메라 활동에서

, 출력 파일 설정 :

LocalSocket outSocket = new LocalSocket(); 

try { 
    outSocket.connect(new LocalSocketAddress(LOCAL_SOCKET)); 
} catch (Exception e) { 
    Log.i(LOG_TAG, "Error connecting socket: "+e); 
} 
mMediaRecorder.setOutputFile(outSocket.getFileDescriptor()); 

LocalServerSocket 구현 :

try { 
    mLocalServerSocket = new LocalServerSocket(mName); 
} catch (Exception e) { 
    Log.e(LOG_TAG, "Error creating server socket: "+e); 
    return; 
} 

while (true) { 

    File out = null; 
    FileOutputStream fop = null; 
    try { 
     mLocalClientSocket = mLocalServerSocket.accept(); 

     InputStream in = mLocalClientSocket.getInputStream(); 

     out = new File(mContext.getExternalFilesDir(null), "testfile.mp4"); 
     fop = new FileOutputStream(out); 

     int len = 0; 
     byte[] buffer = new byte[1024]; 
     while ((len = in.read(buffer)) >= 0) { 

      Log.i(LOG_TAG, "Writing "+len+" bytes"); 
      fop.write(buffer, 0, len); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    finally{ 
     try { 
      fop.close(); 
      mLocalClientSocket.close(); 
     } catch (Exception e2) {} 
    } 
} 

문제는이로 인한 파일이 미디어 플레이어에서 읽을 수없는 것입니다. 이것이 인코딩 문제로 인한 것이라고 생각하십니까? 이 코드는 잘 이해하면 바이너리 파일을 생성해야합니까?!

미리 감사드립니다.

+0

오류가 발생하지 않으면 인코딩/파일 이름 문제로 인한 것일 수 있습니다. 어떤 [OutputFormat] (http://developer.android.com/reference/android/media/MediaRecorder.OutputFormat.html)을 설정 했습니까? 어쩌면 그것을 '.3gp' 또는 그렇게 도와 이름을 바꿉니다 - 여기를 참조하십시오 (http://stackoverflow.com/questions/9110711/android-mediarecorder-getting-3gp-instead-of-mpeg4) – zapl

+0

출력 형식은 MPEG_4, 그래서 나는 그것이 .mp4 확장자로되어 있어야한다고 생각한다. 게다가, mMediaRecorder.setOutputFile()에서 .mp4 파일에 직접 쓰면 완벽하게 작동합니다. – Simon

+0

[mediainfo] (http://mediainfo.sourceforge.net/ko)와 같은 것이 생성 된 비디오의 속성을 읽을 수 있는지 확인 했습니까? 또한 직접 생성 된 파일의 바이너리 diff (최소한 헤더)를 시도 할 수 있으며 생성 된 파일이 올바른지 확인하기 위해 로컬 소켓을 통해 파일을 보냅니다. – zapl

답변

2

좋아, 파일을 재생할 수없는 이유를 발견했습니다.

ftyp3gp4 3gp43gp6 넓은 MDAT HEX에서

0000001866747970336770340000030033677034336770360000000877696465000392D86D6461740000

4 바이트 전 : MP4 및 3GPP 파일에 바이트를 포함하는 헤더가있다 'mdat'태그는 다른 'moov'태그의 위치를 ​​나타냅니다. 파일의 끝. 위치는 일반적으로 녹음이 끝났을 때 설정되지만 MediaRecorder가 소켓을 찾을 수 없기 때문에이 경우이 바이트를 올바른 값으로 설정할 수 없습니다.

이제 내 문제는 녹음이 끝나기 전에 재생되도록하는 것과 같이 파일을 스트리밍 할 수있는 방법을 찾는 것입니다.

+3

스트리밍 할 수있는 솔루션을 찾았습니까? – Houf

+0

안녕 사이먼, 몇 가지 해결책을 찾았습니까? 공유하십시오. 같은 문제에 묶여 있습니다. –

+0

안녕하세요 Ankita. 죄송하지만 지금은 프로젝트를 중단 했으므로이 문제에 대한 작업을 중단했습니다. 이걸로 행운을 빌어. – Simon

1

mp4box를 사용하여 파일을 재구성 할 수 있습니다. moov 상자는 각 오디오 및 비디오 샘플에 대한 색인을 제공합니다. 파일 끝 부분에 있으면 스트리밍이 어려워집니다.

이 도움이 될 수 있습니다 : http://boliston.wordpress.com/tag/moov-box/

또는이 : 0.5 some_file.mp4

-inter mp4box를 당신이 필요한 경우

(나는 현재 시도 할 수있는 기회가 없습니다) 귀하의 애플 리케이션과 함께 작동, 안드로이드에 포트 mp4box에 어떤 활동을 알고 있지 않습니다.

+0

BTW mp4box는 요즘 GPAC 프로젝트의 일부입니다. 우분투에는 최소한 패키지가 있습니다. http://gpac.wp.mines-telecom.fr/ –

0

오늘도 똑같이하려고했지만 mp4는 스트리밍하기 쉽지 않습니다 (일부 부분이 끝나기 전에 말했듯이). 나는 불가능하다고 말하지는 않지만 적어도 아주 어렵게 보인다.

새로운 Android API (4.3)이 될 수 이것은 하나

  • 설정합니다 SurfaceTexture 카메라 미리보기 : camera.setPreviewTexture
  • 기록

이 솔루션의 단점을 OpenGL을하고 MediaCodex + 먹서를 사용하여이 텍스처는 점이다 미리보기 크기가 비디오 크기보다 작을 수 있습니다. 이는 기기에 따라 가장 높은 해상도로 녹화 할 수 없다는 것을 의미합니다. 힌트 : 일부 카메라는 더 높은 미리보기 크기를 지원하지 않지만 카메라가 미리보기 크기를 비디오 크기로 설정하도록 시도 할 수 있다고 말합니다. 그렇게하면 camera.setParameters의 RuntimeException을 catch하고 실패하면 지원되는 미리보기 크기 만 사용하십시오. SurfaceTexture에서 녹음하는 방법

일부 링크 :

Bigflage: great examples for MediaCodec stuff.

The VideoRecorder class from Lablet.

유용 할 수 있습니다 : 없음 spydroid-ipcamera는 RTP 스트림으로 MediaRecorder 소켓에서 데이터를 스트림 그러나 나는 발견했다 MediaCodec에 피드하는 방법. (나는 이미 정확한 NAL 단위 크기를 읽지 못해서 ...)

관련 문제