Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-在我自己的项目中包括本机StageFright功能_Android_Stream_Native_Aac_Stagefright - Fatal编程技术网

Android-在我自己的项目中包括本机StageFright功能

Android-在我自己的项目中包括本机StageFright功能,android,stream,native,aac,stagefright,Android,Stream,Native,Aac,Stagefright,我目前正在开发一个应用程序,需要录制音频,将其编码为AAC,流式传输,并在反向接收流、解码AAC和播放音频中执行相同的操作 我使用成功地录制了AAC(包装在MP4容器中),并使用类成功地上传了音频。但是,我需要能够编码的音频,因为我流它,但这些类似乎没有帮助我做到这一点 我做了一些研究,发现大多数有这个问题的人最终都使用了像ffmpeg这样的本机库 但我想知道,既然Android已经包含了StageFright,它有可以进行编码和解码的本机代码(例如,和),有没有办法在我的应用程序上使用本机代码

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

我使用成功地录制了AAC(包装在MP4容器中),并使用类成功地上传了音频。但是,我需要能够编码的音频,因为我流它,但这些类似乎没有帮助我做到这一点

我做了一些研究,发现大多数有这个问题的人最终都使用了像ffmpeg这样的本机库

但我想知道,既然Android已经包含了StageFright,它有可以进行编码和解码的本机代码(例如,和),有没有办法在我的应用程序上使用本机代码?我该怎么做


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

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

由于stagefright不暴露于NDK,因此您必须进行额外的工作

有两种方法:

(1) 使用android完整源代码树构建您的项目。这种方法需要几天的时间来设置,一旦准备好,就非常简单,您可以充分利用stagefright

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

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

然后,您将通过动态加载libstagefright.so导出库函数,并可以链接到jni项目

使用StatGright进行编码/解码非常简单,只需几百行即可

我使用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();
class ImageSource:公共媒体源{
ImageSource(整数宽度、整数高度、整数颜色格式)
:mWidth(宽度),
mHeight(高度),
mColorFormat(彩色格式)
{
}
虚拟状态读取(
MediaBuffer**缓冲区,常量MediaSource::ReadOptions*选项){
//在这里,您可以用像素填充缓冲区
}
...
};
整数宽度=720;
内部高度=480;
sp img_source=新图像源(宽度、高度、颜色格式);
sp enc_meta=新元数据;
//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,高度);
enc_meta->setInt32(kKeySampleRate,kFramerate);
enc_meta->setInt32(kKeyBitRate、kVideoBitRate);
enc_meta->setInt32(kKeyStride,宽度);
enc_meta->setInt32(高度,高度);
enc_meta->setInt32(kKeyIFramesInterval、kIFramesIntervalSec);
enc_meta->setInt32(kKeyColorFormat,colorFormat);
sp编码器=
OMXCodec::创建(
client.interface(),enc_meta,true,image_source);
sp writer=new-MPEG4Writer(“/sdcard/screenshot.mp4”);
writer->addSource(编码器);
//如果您也想对音频进行编码,可以在此处添加音频源
// 
//sp音频编码器=
//OMXCodec::Create(client.interface(),encMetaAudio,true,audioSource);
//writer->addSource(音频编码器);
writer->setMaxFileDuration(kDurationUs);
检查均衡(OK,writer->start());
而(!writer->reachedEOS()){
fprintf(标准“.”);
美国LEEP(100000);
}
err=writer->stop();

复制时,注意JNI函数是C,Stagefright是C++。Stagefright拉入的一些依赖头看起来与JNI的NDK环境不兼容。请注意,并非所有Android设备都有Stagefright,API因版本而异。要非常小心,因为这些API没有合同,所以它们可能不稳定。我无法对此进行足够的投票,谢谢,关于libstagefright的好信息太少了。你需要从整个Android源代码树中完成这项工作。按照此处的说明操作:,一旦可以构建整个源代码树,就可以使用stagefright。由于stagefright高度依赖于版本,因此需要为每个不同的android版本构建不同的.so文件。在java代码中,您可以基于Android api级别加载这些.so文件。