2012-03-23 7 views
14

현재 오디오 녹음, AAC로 인코딩, 스트리밍, 역방향 수신 스트림, AAC 디코딩 및 오디오 재생에서 동일한 작업을 수행해야하는 응용 프로그램을 개발 중입니다.Android - 내 프로젝트에 기본 StageFright 기능 포함

MediaRecorder을 사용하여 AAC (MP4 컨테이너에 랩핑 됨)를 성공적으로 기록했으며 AudioRecord 클래스를 사용하여 오디오를 성공적으로 업 스트림했습니다. 그러나 오디오를 스트리밍 할 때 오디오를 인코딩 할 수 있어야합니다. 그러나이 클래스 중 어느 것도 내가 그렇게하는 데 도움이되지 않는 것 같습니다.

나는이 문제를 가진 대부분의 사람들이 ffmpeg과 같은 네이티브 라이브러리를 사용하는 것으로 조사한 바 있습니다. 안드로이드는 이미 인코딩 및 디코딩을 할 수있는 네이티브 코드가 스테이지 프라이트를 포함하고 있기 때문에

하지만 궁금 해서요, (예를 들어, AAC encodingAAC decoding는) 내 응용 프로그램에서이 네이티브 코드를 사용하는 방법은 무엇입니까? 어떻게해야합니까?

네이티브 코드로 일부 JNI 클래스 만 구현하면 좋을 것입니다. 또한 Android 라이브러리이기 때문에 라이센스 문제가되지 않습니다 (내가 틀렸다면 수정하십시오).

답변

16

예, libstagefright를 사용할 수 있습니다. 매우 강력합니다.

stagefright는 NDK에 노출되지 않으므로 추가 작업을해야합니다.

(1) 안드로이드 전체 소스 트리를 사용하여 프로젝트를 빌드 :

두 가지 방법이 있습니다. 이 방법은 설치하는 데 며칠 걸립니다. 준비가되면 매우 쉽고 스테이지 프리를 최대한 활용할 수 있습니다.

(2) 당신은 당신의 프로젝트에 파일을 포함 복사 만 할 수 있습니다,이 폴더 안에있다 :

/이 프레임 워크 /베이스/포함 다음/미디어/스테이지 프라이트에게

는 것입니다 안드로이드 - 4.0.4_r1.1 libstagefright.so를 동적으로로드하여 라이브러리 기능을 내 보내면 jni 프로젝트와 연결할 수 있습니다.

statgefright를 사용하여 인코딩/디코딩하려면 매우 간단합니다. 몇 백 줄이 가능합니다.

저는 스크린 샷을 캡처하여 Android VNC 서버에서 사용할 수있는 비디오를 제작하여 곧 출시 될 예정입니다.

다음은 스 니펫입니다. 영화를 인코딩하는 데 ffmpeg를 사용하는 것보다 낫다고 생각합니다. 오디오 소스도 추가 할 수 있습니다.

class ImageSource : public MediaSource { 
    ImageSource(int width, int height, int colorFormat) 
    : mWidth(width), 
     mHeight(height), 
     mColorFormat(colorFormat) 
    { 
    } 

    virtual status_t read(
     MediaBuffer **buffer, const MediaSource::ReadOptions *options) { 
     // here you can fill the buffer with your pixels 
    } 

    ... 
}; 

int width = 720; 
int height = 480; 
sp<MediaSource> img_source = new ImageSource(width, height, colorFormat); 

sp<MetaData> enc_meta = new MetaData; 
// enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 
// enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 
enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 
enc_meta->setInt32(kKeyWidth, width); 
enc_meta->setInt32(kKeyHeight, height); 
enc_meta->setInt32(kKeySampleRate, kFramerate); 
enc_meta->setInt32(kKeyBitRate, kVideoBitRate); 
enc_meta->setInt32(kKeyStride, width); 
enc_meta->setInt32(kKeySliceHeight, height); 
enc_meta->setInt32(kKeyIFramesInterval, kIFramesIntervalSec); 
enc_meta->setInt32(kKeyColorFormat, colorFormat); 

sp<MediaSource> encoder = 
    OMXCodec::Create(
      client.interface(), enc_meta, true, image_source); 

sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/screenshot.mp4"); 
writer->addSource(encoder); 

// you can add an audio source here if you want to encode audio as well 
// 
//sp<MediaSource> audioEncoder = 
// OMXCodec::Create(client.interface(), encMetaAudio, true, audioSource); 
//writer->addSource(audioEncoder); 

writer->setMaxFileDuration(kDurationUs); 
CHECK_EQ(OK, writer->start()); 
while (!writer->reachedEOS()) { 
    fprintf(stderr, "."); 
    usleep(100000); 
} 
err = writer->stop(); 
+2

복사 할 때 JNI 기능이 C이고 Stagefright가 C++임을 유의하십시오. Stagefright가 JNI 용 NDK 환경과 호환되지 않는 것으로 보이는 일부 종속 헤더. –

+2

모든 Android 기기에 무대 장치가있는 것은 아니며 API는 버전에 따라 다릅니다. 이 API에 대한 계약이 없으므로 매우 조심해야 안정적이지 않을 수 있습니다. – dagalpin

+0

StraightFright 이미지를 사용하여 비디오를 렌더링 할 수 있습니까 ?? –