Android - включить собственные функции StageFright в мой собственный проект

В настоящее время я разрабатываю приложение, которое должно записывать аудио, кодировать его как AAC, передавать его и делать то же самое в обратном принимающем потоке, декодировать AAC и воспроизводить аудио.

Я успешно записал AAC (завернутый в контейнер MP4) с помощью MediaRecorder и успешно прослушивая аудио с помощью AudioRecord. Но мне нужно иметь возможность кодировать звук, когда я его передаю, но ни один из этих классов не помогает мне в этом.

Я немного исследовал и обнаружил, что большинство людей, у которых есть эта проблема, заканчиваются использованием родной библиотеки, такой как ffmpeg.

Но мне было интересно, поскольку Android уже включает StageFright, у которого есть собственный код, который может выполнять кодирование и декодирование (например, AAC encoding и AAC decoding), есть ли способ использовать этот собственный код в моем приложении? Как я могу это сделать?

Было бы здорово, если бы мне нужно было реализовать некоторые классы JNI с их собственным кодом. Кроме того, поскольку это Android-библиотека, это не будет проблемой лицензирования (верьте мне, если я ошибаюсь).

14
задан pablitar 23 марта '12 в 3:22
источник поделиться

1 ответ

да, вы можете использовать libstagefright, он очень мощный.

Так как stagefright не подвергается NDK, вам придется выполнять дополнительную работу.

Существует два способа:

(1) создайте свой проект, используя дерево исходных текстов Android. Этот путь занимает несколько дней, чтобы настроить, когда он готов, он очень прост, и вы можете в полной мере использовать stagefright.

(2) вы можете просто скопировать файл include в ваш проект, внутри этой папки:

Android-4.0.4_r1.1/каркасы/основание/включать/медиа/stagefright

то вы будете экспортировать библиотечную функцию, динамически загружая libstagefright.so, и вы можете связать ее с вашим jni-проектом.

Чтобы кодировать/декодировать с помощью statgefright, это очень просто, может сделать несколько сотен строк.

Я использовал stagefright для захвата скриншотов для создания видео, которое будет доступно на нашем 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();
16
ответ дан huisinro 02 мая '12 в 23:18
источник поделиться

Другие вопросы по меткам