package com.yfd.monitor.gdw2019.transmit.event.request.impl;

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

public class RTPVideoSender {

    private DatagramSocket socket;
    private int localPort;
    private String remoteIp;
    private int remotePort;
    private int payloadType; // 在Java中，这通常用于内部处理，不直接发送到网络
    private long ssrc; // 同步源标识符，在Java中作为long处理
    int MTU = 1200; // 最大传输单元

    public RTPVideoSender(int localPort, String remoteIp, int remotePort, int payloadType, long ssrc) {
        this.localPort = localPort;
        this.remoteIp = remoteIp;
        this.remotePort = remotePort;
        this.payloadType = payloadType; // 注意：这个值在Java中可能不直接用于UDP数据包
        this.ssrc = ssrc;

        try {
            this.socket = new DatagramSocket(localPort);
        } catch (Exception e) {
            e.printStackTrace();
            // 处理异常，例如通过抛出异常或记录日志
        }
    }

    public boolean setup(byte[] payload) {
        try {
            // 这里没有直接设置SSRC或payloadType到UDP数据包，因为UDP是无连接的
            // 但你可以在你的应用层协议中包含这些信息

            InetAddress address = InetAddress.getByName(remoteIp);

            // 假设这里有一个方法用于构建包含payloadType和ssrc的RTP数据包
            byte[] rtpPacket = buildRTPPacket(payloadType, ssrc, payload);

            // 发送数据包
            DatagramPacket packet = new DatagramPacket(rtpPacket, rtpPacket.length, address, remotePort);
            socket.send(packet);

            System.out.println("RTP packet sent to " + remoteIp + ":" + remotePort);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 这是一个示例方法，用于构建RTP数据包（实际上你需要根据RTP规范来实现）
    private byte[] buildRTPPacket(int payloadType, long ssrc, byte[] payload) {
        // 这里应该包含实际的RTP头部构建逻辑
        // 但为了简单起见，我们仅返回一个模拟的字节数组
        // 注意：这只是一个示例，实际实现将更复杂
        byte[] header = new byte[12]; // RTP头部通常至少12字节长
        ByteBuffer buffer = ByteBuffer.wrap(header);
        buffer.put((byte) ((2 << 6) & 0xC0)); // 版本号
        buffer.put((byte) 0x00); // 填充和扩展位
        int marker = 0; // 标记位，根据是否是最后一个包来设置

        buffer.put((byte) ((marker << 7) | (payloadType & 0x7F))); // 标记和负载类型
        buffer.putShort((short) 0); // 序列号
        buffer.putInt(0); // 时间戳
        buffer.putInt((int) (Math.random() * Integer.MAX_VALUE)); // SSRC
        // 填充头部（这里省略了实际的头部构建逻辑）

        byte[] fullPacket = new byte[header.length + payload.length];
        System.arraycopy(header, 0, fullPacket, 0, header.length);
        System.arraycopy(payload, 0, fullPacket, header.length, payload.length);

        return fullPacket;
    }

    // 关闭套接字
    public void close() {
        if (socket != null) {
            socket.close();
        }
    }


    public static void main(String[] args) throws Exception {
        RTPVideoSender rtpVideoSender = new RTPVideoSender(5083, "192.168.22.237", 5083,100, 20002343);
        // 构造FFmpeg命令
        String ffmpegCommand = String.format("ffmpeg -i %s -an -vcodec libx264 -f h264 -", "D:\\ffmpeg\\bin\\input.mp4");

        // 启动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[1000];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            // 将读取的 H.264 数据封装成 RTP 包
            rtpVideoSender.setup(buffer);
        }
        process.destroy();
    }
}
