package com.yfd.platform.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

@Slf4j
public class RTPStreamer {

    // 配置参数
    private static final int RTP_PAYLOAD_TYPE = 100; // PT字段，动态类型96
    private static final int RTP_HEADER_SIZE = 12; // RTP头部固定大小
    private static final int MTU = 1000; // 最大传输单元
    private static final int SAMPLE_RATE = 90000; // 时间戳的采样率
    private static final int FRAME_RATE = 30; // 视频帧率
    private static final long TIMESTAMP_INCREMENT = SAMPLE_RATE / FRAME_RATE; // 时间戳增量

    public static void streamVideo(String videoPath, String destinationIp, int destinationPort) throws Exception {
        // 初始化RTP传输参数
        DatagramSocket socket = new DatagramSocket();
        InetAddress address = InetAddress.getByName(destinationIp);
        int sequenceNumber = 0;
        long timestamp = 0;
        int ssrc = (int) (Math.random() * Integer.MAX_VALUE);

        // 构造FFmpeg命令
        String ffmpegCommand = String.format("ffmpeg -i %s -an -vcodec libx264 -bsf:v h264_mp4toannexb -f h264 -", videoPath);

        // 启动FFmpeg进程
        Process process = Runtime.getRuntime().exec(ffmpegCommand);
        InputStream inputStream = process.getInputStream();
        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        // 读取FFmpeg输出（H.264编码数据）
        byte[] buffer = new byte[MTU];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            // 将读取的 H.264 数据封装成 RTP 包
            byte[] rtpPacket = createRTPPacket(buffer, bytesRead, sequenceNumber++, timestamp, ssrc);
            timestamp += TIMESTAMP_INCREMENT;

            // 发送 RTP 包
            DatagramPacket packet = new DatagramPacket(rtpPacket, rtpPacket.length, address, destinationPort);
            socket.send(packet);

            // 打印日志
            log.info("Sent RTP packet, sequence: %d, timestamp: %d, size: %d%n", sequenceNumber, timestamp, bytesRead);
        }

        // 关闭资源
        socket.close();
        process.destroy();

        // 打印 FFmpeg 错误流（如果有）
        String line;
        while ((line = errorReader.readLine()) != null) {
            log.error(line);
        }
    }

    // 构造 RTP 包
    private static byte[] createRTPPacket(byte[] payload, int payloadSize, int sequenceNumber, long timestamp, int ssrc) {
        // RTP头部固定为12字节
        byte[] rtpPacket = new byte[RTP_HEADER_SIZE + payloadSize];
        rtpPacket[0] = (byte) (2 << 6); // Version = 2
        rtpPacket[1] = (byte) RTP_PAYLOAD_TYPE; // PT字段
        rtpPacket[2] = (byte) (sequenceNumber >> 8); // 序列号高字节
        rtpPacket[3] = (byte) (sequenceNumber & 0xFF); // 序列号低字节
        rtpPacket[4] = (byte) (timestamp >> 24); // 时间戳高字节
        rtpPacket[5] = (byte) (timestamp >> 16);
        rtpPacket[6] = (byte) (timestamp >> 8);
        rtpPacket[7] = (byte) (timestamp & 0xFF); // 时间戳低字节
        rtpPacket[8] = (byte) (ssrc >> 24); // SSRC高字节
        rtpPacket[9] = (byte) (ssrc >> 16);
        rtpPacket[10] = (byte) (ssrc >> 8);
        rtpPacket[11] = (byte) (ssrc & 0xFF); // SSRC低字节

        // 复制负载数据
        System.arraycopy(payload, 0, rtpPacket, RTP_HEADER_SIZE, payloadSize);

        return rtpPacket;
    }

    public static void main(String[] args) {
        try {
            // 输入 MP4 文件路径、目标 IP 和端口
            String videoPath = "D:\\ffmpeg\\bin\\encoded_h264.h264";
            String destinationIp = "192.168.22.237";
            int destinationPort = 5083;

            // 启动视频流
            streamVideo(videoPath, destinationIp, destinationPort);
        } catch (Exception e) {
            log.error(e.getMessage());;
        }
    }
}
