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