【问题标题】:Android - Include native StageFright features in my own projectAndroid - 在我自己的项目中包含原生 StageFright 功能
【发布时间】:2012-04-07 14:49:33
【问题描述】:

我目前正在开发一个应用程序,该应用程序需要录制音频、将其编码为 AAC、流式传输,并在反向中执行相同操作 - 接收流、解码 AAC 和播放音频。

我使用 MediaRecorder 成功录制了 AAC(包装在 MP4 容器中),并使用 AudioRecord 类成功上传了音频。但是,我需要能够在流式传输音频时对其进行编码,但这些类似乎都不能帮助我做到这一点。

我研究了一下,发现大多数有这个问题的人最终都会使用像 ffmpeg 这样的原生库。

但我想知道,由于 Android 已经包含 StageFright,它具有可以进行编码和解码的本机代码(例如,AAC encodingAAC decoding),有没有办法使用我的应用程序上的这个本机代码?我该怎么做?

如果我只需要使用它们的本机代码实现一些 JNI 类,那就太好了。另外,由于它是一个 Android 库,因此不会有任何许可问题(如果我错了,请纠正我)。

【问题讨论】:

    标签: android stream native aac stagefright


    【解决方案1】:

    是的,您可以使用 libstagefright,它非常强大。

    由于怯场没有暴露于 NDK,所以你将不得不做额外的工作。

    有两种方式:

    (1) 使用 android 完整源代码树构建您的项目。这种方式需要几天的时间来设置,一旦准备好,它就非常容易,并且您可以充分利用舞台恐惧。

    (2) 您可以将包含文件复制到您的项目中,它位于此文件夹中:

    android-4.0.4_r1.1/frameworks/base/include/media/stagefright

    然后你就可以通过动态加载libstagefright.so来导出库函数,并且可以链接到你的jni项目。

    使用statgefright进行编码/解码,非常简单,几百行就可以了。

    我使用 stagefright 截取屏幕截图以创建一个视频,该视频将在我们的 Android VNC 服务器中提供,即将发布。

    下面是sn-p,我觉得比用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();
    

    【讨论】:

    • 复制的时候注意JNI函数是C,Stagefright是C++。 Stagefright 引入的一些依赖标头看起来与 JNI 的 NDK 环境不兼容。
    • 请注意,并非所有 Android 设备都具有舞台惊吓功能,API 因版本而异。要非常小心,因为这些 API 没有合同,所以它们可能不稳定。
    • 我对此赞不绝口,谢谢,关于 libstagefright 的好信息太少了。
    • 您需要从 Android 的整个源代码树中执行此操作。按照此处的说明进行操作:source.android.com/source/initializing.html,一旦您可以构建整个源代码树,您就可以使用 stagefright。
    • 由于stagefright是高度依赖版本的,所以你需要为每个不同的android版本构建一个不同的.so文件。在您的 java 代码中,您可以根据 Android api 级别加载这些 .so 文件。
    猜你喜欢
    • 2019-11-14
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 2014-11-19
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多