package org.reisa.reisaeye; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; public class FullVideoPush { // 服务地址 private static final String SERVER_URL = "http://localhost:8080"; // 本地视频文件 private static final String VIDEO_FILE = "./a.mp4"; public static void main(String[] args) { try { // 1. 调用Controller创建流 String streamId = "full-video-" + System.currentTimeMillis(); System.out.println("创建流: " + streamId); String pushUrl = createStream(streamId); System.out.println("推流地址: " + pushUrl); // 2. 推送完整视频(直到视频结束) System.out.println("开始推送完整视频..."); pushEntireVideo(pushUrl); System.out.println("视频推送完毕"); // 3. 调用Controller停止流 stopStream(streamId); System.out.println("流程结束"); } catch (Exception e) { System.err.println("推送失败: " + e.getMessage()); e.printStackTrace(); } } // 调用Controller创建流 private static String createStream(String streamId) throws IOException { URL url = new URL(SERVER_URL + "/stream/start?streamId=" + streamId); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); // 解析响应获取推流地址 try (BufferedReader br = new BufferedReader( new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) { String json = br.lines().reduce("", String::concat); return json.split("\"pushUrl\":\"")[1].split("\"")[0]; } finally { conn.disconnect(); } } // 推送完整视频(直到文件结束) private static void pushEntireVideo(String rtmpUrl) throws IOException { // FFmpeg命令:推送完整文件,不限制时长,推完自动结束 String[] cmd = { "ffmpeg", "-re", // 按实际帧率推送 "-i", VIDEO_FILE, // 输入视频文件 "-c:v", "libx264", // 视频编码(兼容RTMP) "-c:a", "aac", // 音频编码 "-f", "flv", // 输出格式 rtmpUrl // 推流地址 }; Process process = new ProcessBuilder(cmd).redirectErrorStream(true).start(); // 打印FFmpeg日志(包含进度) try (BufferedReader br = new BufferedReader( new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { String line; while ((line = br.readLine()) != null) { System.out.println("[FFmpeg] " + line); } } // 等待FFmpeg处理完成(视频推完后进程会自动退出) try { int exitCode = process.waitFor(); if (exitCode != 0) { throw new RuntimeException("FFmpeg推送异常,退出码: " + exitCode); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException("推送被中断"); } } // 调用Controller停止流 private static void stopStream(String streamId) throws IOException { URL url = new URL(SERVER_URL + "/stream/stop?streamId=" + streamId); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.getResponseCode(); // 执行请求 conn.disconnect(); } }