java - 使用AndroidSequenceEncoder时收到 "No frames output"

标签 java android video runtime-error

我正在尝试使用 AndroidSequenceEncoder 创建视频幻灯片。为此,我有一个方法可以检索位图的 ArrayList 和表示视频文件名的字符串。以下是我的方法代码:

public class ImageToVideo
{
    //used to input frames (images) into the video file
    private AndroidSequenceEncoder ase;
    //Arraylist containing the frames to input
    private ArrayList<Bitmap> bi;
    //temporary variable used for AsyncTask below
    private Bitmap image;
    //This method is called until main code can be written to retrieve the proper length of the audio file
    public AndroidSequenceEncoder videoEncode(final ArrayList<Bitmap> images, String filename) throws  IOException
    {
        ase = AndroidSequenceEncoder.createSequenceEncoder(new File(filename), 3);
        bi = images;
        Log.d("SEQUENCEENCODER", "SequenceEncoder created");
        //outer for-loop; goes through each image individually
        for(int i = 0; i < images.size(); i++)
        {
            Log.d("SEQUENCEENCODER", "Retrieving image " + i + " of " + (images.size() - 1));
        //inner for-loop; adds the given image a number of times determined by how long each image is on-screen
        //since encoder's fps is currently set to 3, this loops once for each second the picture should be on-screen times 3
        for(int j = 0; j < 3; j++)
        {
            Log.d("SEQUENCEENCODER", "Encoding image " + i + ", " + (j+1) + " of " + 3);
            image = bi.get((i));
            //used because of error "Choreographer: Skipped ~90 frames! The application may be doing too much work on its main thread"
            AsyncTask.execute(new Runnable()
            {
                @Override
                public void run()
                {
                    try
                    {
                        ase.encodeImage(image);
                    }
                    catch(IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    ase.finish();
    return ase;
}

AndroidSequenceEncoder的fps临时设置为3;当我更多地处理代码时,我希望此方法也采用视频的长度,以便该方法根据每个图像在屏幕上显示的时间长度来确定 fps,前提是它们每个都有相同的时间。使用 4 张图像运行此方法时,我收到以下消息

D/SEQUENCEENCODER: SequenceEncoder created
D/SEQUENCEENCODER: Retrieving image 0 of 3
D/SEQUENCEENCODER: Encoding image 0, 1 of 3
D/SEQUENCEENCODER: Encoding image 0, 2 of 3
D/SEQUENCEENCODER: Encoding image 0, 3 of 3
D/SEQUENCEENCODER: Retrieving image 1 of 3
D/SEQUENCEENCODER: Encoding image 1, 1 of 3
D/SEQUENCEENCODER: Encoding image 1, 2 of 3
D/SEQUENCEENCODER: Encoding image 1, 3 of 3
D/SEQUENCEENCODER: Retrieving image 2 of 3
D/SEQUENCEENCODER: Encoding image 2, 1 of 3
D/SEQUENCEENCODER: Encoding image 2, 2 of 3
D/SEQUENCEENCODER: Encoding image 2, 3 of 3
D/SEQUENCEENCODER: Retrieving image 3 of 3
D/SEQUENCEENCODER: Encoding image 3, 1 of 3
D/SEQUENCEENCODER: Encoding image 3, 2 of 3
D/SEQUENCEENCODER: Encoding image 3, 3 of 3
I/System.out: [WARN]    . (:0): No frames output.
D/EGL_emulation: eglMakeCurrent: 0xa8a05240: ver 2 0 (tinfo 0xa8a03250)
D/EGL_emulation: eglMakeCurrent: 0xa8a05240: ver 2 0 (tinfo 0xa8a03250)
I/chatty: uid=10080(projectname) RenderThread identical 1 line
D/EGL_emulation: eglMakeCurrent: 0xa8a05240: ver 2 0 (tinfo 0xa8a03250)
I/zygote: Do partial code cache collection, code=122KB, data=94KB
I/zygote: After code cache collection, code=117KB, data=92KB
I/zygote: Increasing code cache capacity to 512KB

后面是一长串指向命令的系统错误

ase.encodeImage(image);

在 Android 虚拟设备中确实创建了一个新的视频文件,但它几乎在播放后立即结束,尽管它说它的长度是 4 秒。我想知道我在代码中做错了什么导致了这种情况。

最佳答案

我在上面的代码中看到的一个问题是帧的实际编码发生在一个单独的(后台)线程中。因此,在某些情况下,可能在调用“完成”时实际上没有任何帧被编码。 您需要做的是确保在所有帧的编码实际发生之后调用“完成”。有多种方法可以实现这一点:

  1. 将循环完全移动到异步任务中,然后完成;
  2. 如果只有一个执行程序线程,您也可以在异步任务中执行“完成”,这样您将依靠内部执行程序队列在最后执行“完成”;
  3. 使用线程同步原语,例如“等待/通知”。因此,在主线程中,您可以在调用“完成”之前“等待”,而在异步任务中,您将“通知”。虽然这是一个可行的选择,但出于各种其他原因,我强烈建议您不要使用它。

关于java - 使用AndroidSequenceEncoder时收到 "No frames output",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47588301/

相关文章:

android - Selenium 2.41 - 无法启动 Firefox

android - 如何在 Flutter 发布的 apk 中禁用代码混淆?

google-chrome - 两个 H.264 mp4 视频 : One plays in Chrome, 一个没有

c++ - 如何在 C++ 中检查给定文件是否是有效的视频文件?

java - 带条件的 mongotemplate 聚合

java - Android应用程序打开时关闭

java - 以编程方式更改模型纹理 libgdx

java - 如何清除浏览器缓存?

android - 使用 ACTION_IMAGE_CAPTURE 时无法连接到相机服务

ios - OpenGL ES 2.0 到 iPad/iPhone 上的视频