a-schild / jave2

The JAVE (Java Audio Video Encoder) library is Java wrapper on the ffmpeg project
GNU General Public License v3.0
1.28k stars 249 forks source link

ws.schild.jave.EncoderException: Exit code of ffmpeg encoding run is 137(Docker:linux) #234

Open darwindu opened 1 year ago

darwindu commented 1 year ago

The Win10 environment is running normally;

Docker environment running Exception; Docker OS: Linux x86_64 x86_64 GNU/Linux Linux version 4.14.105-19-0008 (gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC))

How to solve ?

log:

企业微信截图_16837998943202
public static File compressVideoByFile(File sourceFile, File targetFile) throws Exception {
        String bizSeqNo = MumbleContextUtil.getBizSeqNo();
        String fileName = sourceFile.getName();
        //参数:
        int maxBitRate = 128000; //设置最大值:比特率越高,清晰度/音质越好
        int maxSamplingRate = 0; //44100; //设置编码时候的音量值,未设置为0,如果256,则音量值不会改变 // 采样率就是44.1KHz这个值
        int bitRate = 2000000; // 设置音频比特率,单位:b (比特率越高,清晰度/音质越好,当然文件也就越大 800000 = 800kb)
        int maxFrameRate = 20; // 视频帧率:15 f / s 帧率越低,效果越差
        int maxWidth = 1920;    //视频最大宽度(这里没使用)
        try {
            MultimediaObject object = new MultimediaObject(sourceFile);
            // 视频属性设置
            AudioInfo audioInfo = object.getInfo().getAudio();
            log.info("{} 视频属性设置audioInfo:", bizSeqNo, JSON_MAPPER.toJson(audioInfo));
            AudioAttributes audio = new AudioAttributes();
            // 设置通用编码格式
            audio.setCodec("aac");
            if (audioInfo.getBitRate() > maxBitRate) {
                audio.setBitRate(new Integer(maxBitRate));
            }
            audio.setChannels(audioInfo.getChannels());
            if (audioInfo.getSamplingRate() > maxSamplingRate) {
                audio.setSamplingRate(maxSamplingRate);
            }
            // 视频编码属性配置
            VideoInfo videoInfo = object.getInfo().getVideo();
            log.info("{} 视频编码属性配置videoInfo:", bizSeqNo, JSON_MAPPER.toJson(videoInfo));
            VideoAttributes video = new VideoAttributes();
            video.setCodec("h264");
            if (videoInfo.getBitRate() > bitRate) {
                video.setBitRate(bitRate);
            }
            if (videoInfo.getFrameRate() > maxFrameRate) {
                video.setFrameRate(maxFrameRate);
            }
            EncodingAttributes attr = new EncodingAttributes();
            //attr.setFormat("mp4");
            attr.setAudioAttributes(audio);
            attr.setVideoAttributes(video);
            log.info("{} attr:", bizSeqNo, JSON_MAPPER.toJson(attr));
            Encoder encoder = new Encoder();
            encoder.encode(new MultimediaObject(sourceFile), targetFile, attr);
            log.info("{} 压缩后视频大小:[{}]bytes", bizSeqNo, targetFile.length());
            //String base64FromFile = getBase64FromFile(targetFile);
            //压缩后的base64转视频文件,可查看压缩后的视频:
            //getFileFromBase64(base64FromFile,null);
            return targetFile;
        } catch (Exception e) {
            log.error("{} 异常", bizSeqNo, e);
            throw e;
        }
    }
a-schild commented 1 year ago

https://stackoverflow.com/questions/19548027/ffmpeg-closes-with-return-code-137

Not enough memory or some other limits set?

darwindu commented 1 year ago

https://stackoverflow.com/questions/19548027/ffmpeg-closes-with-return-code-137

Not enough memory or some other limits set?

Memory analysis: Test environment with 2GB of memory, upload video size of 25M, and use about 10M for compression. The memory is enough

Is the limits? Which value should be modified? open file=1048576 【ulimit -a】:

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 251517
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1048576
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

【log】 企业微信截图_16838597709373

lanmaypin commented 1 year ago

137 How to make an error in the end is decided?

lanmaypin commented 1 year ago

https://stackoverflow.com/questions/19548027/ffmpeg-closes-with-return-code-137 Not enough memory or some other limits set?

Memory analysis: Test environment with 2GB of memory, upload video size of 25M, and use about 10M for compression. The memory is enough

Is the limits? Which value should be modified? open file=1048576 【ulimit -a】:

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 251517
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1048576
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

【log】 企业微信截图_16838597709373

How to make an error in the end is decided?

a-schild commented 1 year ago

The exit code 137 is returned by the underlying operating system, and there is nothing I can do from java to catch this. I can just report it as the cause, why the process did abort.

When you say that the OS (Docker) has 2GB of ram, then this is not the free ram, but overall ram of this instance. This memory is then shared by Docker/Java/ffmpeg and all other processes running in that instance.

Have you tried doubling ram?