标签: mediaextractor

SurfaceTexture的onFrameAvailable()方法总是被调用太晚了

我正在尝试使用以下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 opengl-es mediacodec mediaextractor

22
推荐指数
1
解决办法
1万
查看次数

在Android上以编程方式获取MPEG-4视频流的配置文件

有没有办法使用标准Android API 获取MPEG-4视频文件的个人资料代码?

示例配置文件的代码如下:baseline,main,high等.

我不想ffmpeg在Android应用程序中包含二进制文件以获取此信息.

我在MediaCodecInfo.CodecProfileLevel类中找到了配置文件列表的引用.任何人都可以确认这是否是我应该使用的那个?

以下是从MX Player应用程序中 获取的视频信息的示例屏幕截图带视频资料的示例数据


  • 更新#1:我查看了MX Player应用程序,看起来他们使用ffmpeg二进制文件,所以我可以肯定地说他们使用它来提取profile-code.
  • 更新#2:我也查看了ExoPlayer v1 API,它们似乎也没有特定的API来获取此信息.

android mpeg-4 android-mediaplayer mediaextractor android-mediacodec

11
推荐指数
1
解决办法
954
查看次数

MediaMuxer无法制作可流式传输的MP4

我在Android上使用MediaExtractor编辑MP4来获取音频和视频曲目,然后使用MediaMuxer创建新文件.它工作正常.我可以在手机(和其他播放器)上播放新的MP4,但无法在网络上传输文件.当我停止MediaMuxer时,它会生成一条日志消息

"mp4文件不会流式传输."

我查看了底层的本机代码(MPEG4Writer.cpp),看起来编写器在计算所需的moov盒大小时遇到​​了麻烦.如果没有将比特率作为参数提供给作者,它会尝试使用某种启发式进行猜测.问题是MediaMuxer无法提供设置MPEG4Writer参数的功能.我是否遗漏了某些东西,或者我是不是在寻找其他一些生成文件(或标题)的方法?谢谢.

video android mediaextractor mediamuxer

8
推荐指数
1
解决办法
2604
查看次数

解码音频文件并重新编码为所需的PCM格式:44,100 kHz,2通道,16位

我想将音频文件解码为原始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实例并且可以为我提供一个工作示例?

audio android pcm mediacodec mediaextractor

7
推荐指数
1
解决办法
4218
查看次数

Android MediaExtractor和mp3流

我正在尝试使用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)

audio mp3 android mediacodec mediaextractor

7
推荐指数
1
解决办法
1万
查看次数

Android MediaExtractor / MediaCodec 本机崩溃

我在 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 …

memory android bytebuffer mediaextractor android-mediacodec

6
推荐指数
0
解决办法
695
查看次数

使用MediaCodec和MediaExtractor解码和编码视频

我需要将视频解码为一系列位图,以便我能够修改它们,然后将它们压缩回android中的视频文件.

我计划通过使用getFrameAtTime并将其保存到图像序列来管理它.然后我可以修改序列中的图像并将其编码回电影.但我有两个问题:

  • 首先,在我阅读时,getFrameAtTime它用于创建缩略图,并且不保证返回正确的帧.这使视频滞后.
  • 其次,保存图像并将其读回需要很长时间.

我读到使用MediaExtractor进行解码的正确方法,这很好,但我只有示例直接将它呈现给a surfaceView.有什么方法可以将我转换outputBuffer为位图吗?

我需要它来使用16级及以上的api级别.

video android bitmap mediacodec mediaextractor

5
推荐指数
1
解决办法
7626
查看次数

Android精确搜索视频

我正在努力使用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)

android seek mediacodec mediaextractor grafika

5
推荐指数
1
解决办法
1359
查看次数

如何将rtsp数据提取到MediaCodec中

我在使用MediaPlayer播放RTSP流时遇到问题,因此我决定使用较低级别的API - MediaExtractor和MediaCodec.

问题是MediaExtractor的setDataSource()方法不接受RTSP流.

所以,我的问题是,如何将rtsp数据导入MediaCodec输入缓冲区?

java android rtsp mediacodec mediaextractor

5
推荐指数
0
解决办法
549
查看次数

通过 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)

video android opengl-es mediaextractor android-mediacodec

5
推荐指数
1
解决办法
4609
查看次数