Skip to content

converting avi-format-video file to m3u8 with Video codec not found. #2317

@zzhua195

Description

@zzhua195

It works fine when I convert mp4-format-video file to m3u8 with encryption,but I try a avi video file,it occurs this problem:

org.bytedeco.javacv.FFmpegFrameRecorder$Exception: avcodec_find_encoder() error: Video codec not found. (For more details, make sure FFmpegLogCallback.set() has been called.)
	at org.bytedeco.javacv.FFmpegFrameRecorder.startUnsafe(FFmpegFrameRecorder.java:537)
	at org.bytedeco.javacv.FFmpegFrameRecorder.start(FFmpegFrameRecorder.java:437)
	at org.bytedeco.javacv.FFmpegFrameRecorder.start(FFmpegFrameRecorder.java:432)
	at com.zzhua.controller.HlsEncryptConverter.convertToEncryptedHls(HlsEncryptConverter.java:65)
	at com.zzhua.controller.HlsEncryptConverter.main(HlsEncryptConverter.java:120)

following dependencies:
javacv.version => 1.5.9
ffmpeg-platform => 6.0-1.5.9

import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Base64;

public class HlsEncryptConverter {


    public static void convertToEncryptedHls(String inputPath, String outputDir, String hlsBaseUrl) throws Exception {
        // 生成随机密钥(16 bytes for AES-128)
        byte[] key = new byte[16];
        new SecureRandom().nextBytes(key);
        String keyHex = bytesToHex(key);
        
        // 生成IV(可选)
        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);
        String ivHex = bytesToHex(iv);

        // 保存密钥到文件
        String keyFileName = "encryption.key";
        saveKeyFile(outputDir + File.separator + keyFileName, key);

        FFmpegLogCallback.set();

        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputPath);
        grabber.start();

        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(
                outputDir + File.separator + "output.m3u8",
                grabber.getImageWidth(),
                grabber.getImageHeight(),
                grabber.getAudioChannels()
        );

        // 通用HLS配置
        recorder.setFormat("hls");
        recorder.setOption("hls_time", "10");          // 每个TS分片10秒
        recorder.setOption("hls_list_size", "0");       // 无限播放列表
        recorder.setOption("hls_segment_type", "mpegts");
        recorder.setOption("hls_key_info_file", generateKeyInfoFile(outputDir, keyFileName, ivHex, hlsBaseUrl));
        recorder.setOption("hls_flags", "independent_segments");
        
        // 视频编码配置(兼容性配置)
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setVideoOption("preset", "medium");
        recorder.setVideoBitrate(grabber.getVideoBitrate());
        recorder.setVideoOption("tune", "film");
        
        // 音频编码配置
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        recorder.setAudioBitrate(grabber.getAudioBitrate());
        recorder.setSampleRate(grabber.getSampleRate());
        
        // 强制使用PTS作为时间戳
        // recorder.setOption("use_wallclock_as_timestamps", "1");
        
        recorder.start(grabber.getFormatContext());
        AVPacket packet;
        while ((packet = grabber.grabPacket()) != null) {
            try {
                recorder.recordPacket(packet);
            } catch (FrameRecorder.Exception e) {
                e.printStackTrace();
            }
        }
        recorder.setTimestamp(grabber.getTimestamp());
        recorder.stop();
        recorder.release();
        grabber.stop();
        grabber.release();

        recorder.close();
        grabber.close();
    }

    private static String generateKeyInfoFile(String outputDir, String keyFileName, String iv, String baseUrl) throws IOException {
        String keyInfoPath = outputDir + File.separator + "enc.keyinfo";
        String keyUrl = baseUrl + keyFileName;
        
        try (FileOutputStream fos = new FileOutputStream(keyInfoPath)) {
            String content = keyUrl + "\n" + outputDir + File.separator + keyFileName + "\n" + iv;
            fos.write(content.getBytes());
        }
        return keyInfoPath;
    }

    private static void saveKeyFile(String path, byte[] key) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(path)) {
            fos.write(key);
        }
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        try {
            /*
            // success case
            String input = "D:\\temp\\test2\\test2.mp4";
            String outputDir = "D:\\temp\\test2";
            String baseUrl = "https://your-cdn.com/";
            */

            // fail case
            String input = "D:\\temp\\test1\\test1.avi";
            String outputDir = "D:\\temp\\test1";
            String baseUrl = "https://your-cdn.com/";
            
            new File(outputDir).mkdirs();
            convertToEncryptedHls(input, outputDir, baseUrl);
            System.out.println("转换完成!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions