我正在尝试使用以下MediaExtractor示例:
http://bigflake.com/mediacodec/ - ExtractMpegFramesTest.java(需要4.1,API 16)
我遇到的问题是outputSurface.awaitNewImage(); 似乎总是抛出RuntimeException("frame wait timed out"),每当mFrameSyncObject.wait(TIMEOUT_MS)调用超时时抛出它.无论我设置什么TIMEOUT_MS,onFrameAvailable()总是在超时发生后立即调用.我尝试了50毫秒和30000毫秒,它是相同的.
似乎onFrameAvailable()在线程繁忙时无法进行调用,并且一旦超时发生并结束线程代码执行,它就可以解析onFrameAvailable()调用.
有没有人设法让这个例子工作,或者知道MediaExtractor应该如何使用GL纹理?
编辑:在使用API 4.4和4.1.1的设备上尝试了这一点,两者都发生了同样的情况.
编辑2:
得益于fadden 4.4.问题是ExtractMpegFramesWrapper.runTest()调用的方法th.join();阻塞了主线程并阻止了onFrameAvailable()调用的处理.一旦我评论th.join();它就适用于4.4.我想也许ExtractMpegFramesWrapper.runTest()本身应该在另一个线程上运行,所以主线程没有被阻止.
4.1.2调用时还有一个小问题codec.configure(),它给出了错误:
A/ACodec(2566): frameworks/av/media/libstagefright/ACodec.cpp:1041 CHECK(def.nBufferSize >= size) failed.
A/libc(2566): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 2625 (CodecLooper)
Run Code Online (Sandbox Code Playgroud)
通过在通话前添加以下内容我解决了这个问题:
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 0);
Run Code Online (Sandbox Code Playgroud)
然而,我现在在4.1.1(Galaxy S2 GT-I9100)和4.1.2(三星Galaxy Tab GT-P3110)上的问题是它们都始终将info.size设置为0以用于所有帧.这是日志输出:
loop
input buffer not available
no output from decoder available
loop
input …Run Code Online (Sandbox Code Playgroud) 有没有办法使用标准Android API 获取MPEG-4视频文件的个人资料代码?
示例配置文件的代码如下:baseline,main,high等.
我不想ffmpeg在Android应用程序中包含二进制文件以获取此信息.
我在MediaCodecInfo.CodecProfileLevel类中找到了配置文件列表的引用.任何人都可以确认这是否是我应该使用的那个?
以下是从MX Player应用程序中
获取的视频信息的示例屏幕截图
ffmpeg二进制文件,所以我可以肯定地说他们使用它来提取profile-code. android mpeg-4 android-mediaplayer mediaextractor android-mediacodec
我在Android上使用MediaExtractor编辑MP4来获取音频和视频曲目,然后使用MediaMuxer创建新文件.它工作正常.我可以在手机(和其他播放器)上播放新的MP4,但无法在网络上传输文件.当我停止MediaMuxer时,它会生成一条日志消息
"mp4文件不会流式传输."
我查看了底层的本机代码(MPEG4Writer.cpp),看起来编写器在计算所需的moov盒大小时遇到了麻烦.如果没有将比特率作为参数提供给作者,它会尝试使用某种启发式进行猜测.问题是MediaMuxer无法提供设置MPEG4Writer参数的功能.我是否遗漏了某些东西,或者我是不是在寻找其他一些生成文件(或标题)的方法?谢谢.
我想将音频文件解码为原始PCM数据,以将其流式传输到本地网络中的播放设备.我使用了引入API级别16 的新MediaExtractor和MediaCodec类.该器件要求PCM数据为44,100 kHz,有2个通道和16位样本大小.只要输入文件大致符合这些要求,这就可以正常工作.但是,无论何时我正在解码使用的文件 - 例如 - 32,000 kHz的采样率并且可能只有一个通道,那么我无法从MediaCodec类获得所需的输出.
因为我似乎无法指定MediaCodec类的输出格式.所以我决定实例化另一个MediaCodec对象,将原始数据重新编码为我想要的格式.根据Android 4.1 支持的媒体格式列表,Android支持编码到PCM/Wave.但是我无法创建编码为PCM/Wave的MediaCodec对象.我尝试将各种MIME类型传递给MediaCodec.createEncoderByType(type); 但我总是以IOException失败:
java.io.IOException: Failed to allocate component instance
at android.media.MediaCodec.native_setup(Native Method)
at android.media.MediaCodec.<init>(MediaCodec.java:210)
at android.media.MediaCodec.createEncoderByType(MediaCodec.java:194)
[..]
Run Code Online (Sandbox Code Playgroud)
有没有人能够成功创建编码为PCM/Wave的MediaCodec实例并且可以为我提供一个工作示例?
我正在尝试使用MediaExtractor/MediaCodec播放mp3流.由于延迟和长缓冲区大小,MediaPlayer是不可能的.
我找到的唯一示例代码是:http://dpsm.wordpress.com/category/android/
代码示例只是parcial(?)并使用File而不是stream.
我一直在尝试调整这个例子来播放音频流,但我无法理解它应该如何工作.像往常一样Android文档没有帮助.
据我所知,首先我们获取有关流的信息,可能是使用此信息设置AudioTrack(代码示例包括AudioTrack初始化?)然后打开输入缓冲区和输出缓冲区.
我已经为此重新创建了代码,我可以猜到这将是缺少的部分,但没有音频出来.
有人能指出我正确的方向,以了解这应该如何工作?
public final String LOG_TAG = "mediadecoderexample";
private static int TIMEOUT_US = -1;
MediaCodec codec;
MediaExtractor extractor;
MediaFormat format;
ByteBuffer[] codecInputBuffers;
ByteBuffer[] codecOutputBuffers;
Boolean sawInputEOS = false;
Boolean sawOutputEOS = false;
AudioTrack mAudioTrack;
BufferInfo info;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url = "http://82.201.100.9:8000/RADIO538_WEB_MP3";
extractor = new MediaExtractor();
try {
extractor.setDataSource(url);
} catch (IOException e) {
}
format = extractor.getTrackFormat(0);
String mime = format.getString(MediaFormat.KEY_MIME);
int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE); …Run Code Online (Sandbox Code Playgroud) 我在 Android 中开发了一个简单的音频播放器,可以播放 .mp3 文件。为了解码文件,我使用 Android MediaExtractor 和 Android MediaCodec。示例代码如下所示:
int inIndex = mDecoder.dequeueInputBuffer(TIMEOUT_US);
if (inIndex >= 0) {
ByteBuffer buffer = inputBuffers[inIndex];
int sampleSize = mExtractor.readSampleData(buffer, 0);
if (sampleSize < 0) {
// We shouldn't stop the playback at this point, just pass the EOS
// flag to mDecoder, we will get it again from the
// dequeueOutputBuffer
Log.d(TAG, "InputBuffer BUFFER_FLAG_END_OF_STREAM");
mDecoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
}
else {
mDecoder.queueInputBuffer(inIndex, 0, sampleSize, mExtractor.getSampleTime(), 0);
mExtractor.advance();
}
Run Code Online (Sandbox Code Playgroud)
在我的所有测试设备上,代码运行没有任何问题。然而,在 Google Play …
我需要将视频解码为一系列位图,以便我能够修改它们,然后将它们压缩回android中的视频文件.
我计划通过使用getFrameAtTime并将其保存到图像序列来管理它.然后我可以修改序列中的图像并将其编码回电影.但我有两个问题:
getFrameAtTime它用于创建缩略图,并且不保证返回正确的帧.这使视频滞后.我读到使用MediaExtractor进行解码的正确方法,这很好,但我只有示例直接将它呈现给a surfaceView.有什么方法可以将我转换outputBuffer为位图吗?
我需要它来使用16级及以上的api级别.
我正在努力使用MediaExtractor进行精确搜索seekTo().虽然我可以毫无问题地寻求同步帧,但我想寻求具体的时间.这个问题让我想到了如何做到这一点,但我不确定它们是否有效.基本上,我必须寻找最接近的前一个同步帧,然后寻求advance()提取器,直到达到目标时间.该过程中的每个帧将被馈送到解码器,即第一个I帧和其余的P帧.这是相关的代码段(基于google/grafika的MoviePlayer):
extractor.seekTo((long) seekTarget[threadNr], MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
...
while (extractor.getSampleTime() < (long) seekTarget[threadNr]) {
Log.d(TAG, "Thread " + threadNr + " advanced to timestamp " + extractor.getSampleTime());
int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
if (inputBufIndex >= 0) {
ByteBuffer inBufer = decoderInputBuffers[inputBufIndex];
int chunkSize = extractor.readSampleData(inBufer, 0);
if (chunkSize < 0) {
// End of stream -- send empty frame with EOS flag set.
decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L,
MediaCodec.BUFFER_FLAG_END_OF_STREAM);
inputDone = true;
if (VERBOSE) Log.d(TAG, "sent input …Run Code Online (Sandbox Code Playgroud) 我在使用MediaPlayer播放RTSP流时遇到问题,因此我决定使用较低级别的API - MediaExtractor和MediaCodec.
问题是MediaExtractor的setDataSource()方法不接受RTSP流.
所以,我的问题是,如何将rtsp数据导入MediaCodec输入缓冲区?
我正在尝试实现https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java 但通过使用修改源一个视频文件 mp4。mime 类型为 video/avc,比特率 288kbps,iframeinterval 100,宽度:176,高度:144。文件大小为 6MB。当我解码视频并将帧放入输出表面时,我可以将帧保存到位图并查看帧。但是最后,在编码后(使用与原始视频相同的参数),我得到了一个700kb的文件,却看不到视频(可能是文件损坏了)。
extractor = new MediaExtractor();
extractor.SetDataSource(filePath);
for (int i = 0; i < extractor.TrackCount; i++)
{
inputFormat = extractor.GetTrackFormat(i);
string mime = inputFormat.GetString(MediaFormat.KeyMime);
if (mime.StartsWith("video/"))
{
extractor.SelectTrack(i);
mimeType = mime;
break;
}
}
mWidth = inputFormat.GetInteger(MediaFormat.KeyWidth);
mHeight = inputFormat.GetInteger(MediaFormat.KeyHeight);
// Create an encoder format that matches the input format. (Might be able to just
// re-use the format used to generate the video, since we want it to be the same.)
MediaFormat …Run Code Online (Sandbox Code Playgroud) android ×10
mediaextractor ×10
mediacodec ×6
video ×3
audio ×2
opengl-es ×2
bitmap ×1
bytebuffer ×1
grafika ×1
java ×1
mediamuxer ×1
memory ×1
mp3 ×1
mpeg-4 ×1
pcm ×1
rtsp ×1
seek ×1