bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.58k stars 1.58k forks source link

Unable to push to srs server #2232

Open whr2349 opened 5 months ago

whr2349 commented 5 months ago

public void toSrsPush(String cameraId) {

    String rtmpUrl = "rtmp://localhost/live/livestream";
    System.out.println("Starting streaming for " + cameraId);
    try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(cameraId);
         FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(rtmpUrl, grabber.getImageWidth(),grabber.getImageHeight(),grabber.getAudioChannels())) {
        grabber.setOption("rtsp_transport", "tcp");
        grabber.start();
        System.out.println(grabber.getFrameRate());
        System.out.println(grabber.getImageWidth());
        System.out.println(grabber.getImageHeight());
        System.out.println(grabber.getAudioChannels());
        recorder.setVideoOption("preset", "ultrafast");
        recorder.setVideoOption("tune", "zerolatency");

        // // 判断源是否为HEVC并需要重新编码
        // boolean isHEVC = grabber.getVideoCodec() == avcodec.AV_CODEC_ID_HEVC;
        //
        // // 如果源是HEVC,将录制器编解码器设置为H.264
        // if (isHEVC) {
        //     recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        //     System.out.println("正在将HEVC重新编码为H.264");
        // }

        // 设置默认帧率
        double frameRate = 20;
        if (grabber.getFrameRate() > 0) {
            frameRate = grabber.getFrameRate();
        }

        // 设置默认视频比特率
        int videoBitrate = 4000000; // 默认为 4 Mbps
        if (grabber.getVideoBitrate() > 0) {
            videoBitrate = grabber.getVideoBitrate();
        }

        if (grabber.getAudioChannels() > 0) {
            recorder.setAudioChannels(grabber.getAudioChannels());
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);// 设置音频编解码器
            recorder.setSampleRate(grabber.getSampleRate());// 设置采样率
            recorder.setAudioBitrate(grabber.getAudioBitrate()); // 或使用 grabber.getAudioBitrate() 如果它返回有效值
        } else {
            recorder.setAudioChannels(0); // 设置为0表示没有音频
        }

        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        // recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        recorder.setFormat("flv");
        recorder.setFrameRate(frameRate);// 设置帧率
        // recorder.setSampleRate(grabber.getSampleRate());
        // recorder.setAudioBitrate(grabber.getAudioBitrate());
        recorder.setVideoBitrate(videoBitrate);

        System.out.println("Frame rate: " + frameRate);
        System.out.println("Video bitrate: " + videoBitrate);
        System.out.println("Audio channels: " + grabber.getAudioChannels());
        System.out.println("Sample rate: " + grabber.getSampleRate());
        System.out.println("Audio bitrate: " + grabber.getAudioBitrate());

        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); // 确保与RTMP兼容

        recorder.start(); // 启动录制器

        Frame frame;
        while ((frame = grabber.grab()) != null) {
            System.out.println("Frame grabbed: " + frame);
            recorder.record(frame); // 将捕获的帧录制到RTMP流中
        }

        recorder.stop(); // 停止录制
        grabber.stop();
        System.out.println("对 " + cameraId + " 的流媒体传输已完成");
    } catch (FrameGrabber.Exception | FrameRecorder.Exception e) {
        System.err.println("流媒体传输过程中出现错误: " + e.getMessage());
        e.printStackTrace();
    }
    // this.executeFFmpegCommand(cameraId, rtmpUrl);
}
同样的代码1.5.9版本可以推送到srs服务器,而1.5.10不行,请问为什么??

The same code version 1.5.9 can be pushed to srs server, but 1.5.10 can not, please ask why?

saudet commented 5 months ago

The hack that used to work for this doesn't work anymore since FFmpeg 6.1. It needs to be upgraded it here: https://github.com/bytedeco/javacpp-presets/blob/master/ffmpeg/cppbuild.sh#L122 /cc @nanguantong