MediaTransferHls.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package com.zj.thread;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import com.zj.common.MediaConstant;
  8. import com.zj.dto.CameraDto;
  9. import cn.hutool.core.collection.CollUtil;
  10. import lombok.extern.slf4j.Slf4j;
  11. /**
  12. * hls切片
  13. * @author ZJ
  14. *
  15. */
  16. @Slf4j
  17. public class MediaTransferHls extends MediaTransfer {
  18. /**
  19. * 运行状态
  20. */
  21. private boolean running = false;
  22. private boolean enableLog = false;
  23. private Process process;
  24. private Thread inputThread;
  25. private Thread errThread;
  26. private int port = 8888;
  27. /**
  28. * 相机
  29. */
  30. private CameraDto cameraDto;
  31. /**
  32. * cmd
  33. */
  34. private List<String> command = new ArrayList<>();
  35. public boolean isRunning() {
  36. return running;
  37. }
  38. public void setRunning(boolean running) {
  39. this.running = running;
  40. }
  41. /**
  42. *
  43. * @param cameraDto
  44. */
  45. public MediaTransferHls(CameraDto cameraDto, int port) {
  46. this.cameraDto = cameraDto;
  47. this.port = port;
  48. buildCommand();
  49. }
  50. /**
  51. * String cmd = "ffmpeg -i rtsp://admin:VZCDOY@192.168.2.120:554/Streaming/Channels/102 -r 25 -g 25 -c:v libx264 -c:a aac -f hls -hls_list_size 1 -hls_wrap 6 -hls_time 1 -hls_base_url /ts/"+22+"/ -method put http://localhost:8888/record/"+22+"/out.m3u8";
  52. */
  53. private void buildCommand() {
  54. command.add(System.getProperty(MediaConstant.ffmpegPathKey));
  55. // 本地文件 解决文件分片速度过快导致前端跳帧问题
  56. if(cameraDto.getType() == 1) {
  57. command.add("-re");
  58. }
  59. command.add("-i");
  60. command.add(cameraDto.getUrl());
  61. command.add("-r");
  62. command.add("25");
  63. command.add("-g");
  64. command.add("25");
  65. command.add("-c:v");
  66. command.add("libopenh264"); //javacv 1.5.5 无法使用libx264
  67. command.add("-c:a");
  68. command.add("aac");
  69. command.add("-f");
  70. command.add("hls");
  71. command.add("-hls_list_size");
  72. command.add("1");
  73. command.add("-hls_wrap");
  74. command.add("6");
  75. command.add("-hls_time");
  76. command.add("1");
  77. command.add("-hls_base_url");
  78. command.add("/ts/"+cameraDto.getMediaKey()+"/");
  79. command.add("-method");
  80. command.add("put");
  81. command.add("http://localhost:"+port+"/record/"+cameraDto.getMediaKey()+"/out.m3u8");
  82. }
  83. /**
  84. * 执行
  85. */
  86. public void execute() {
  87. String join = CollUtil.join(command, " ");
  88. log.info(join);
  89. try {
  90. process = new ProcessBuilder(command).start();
  91. running = true;
  92. dealStream(process);
  93. } catch (IOException e) {
  94. running = false;
  95. e.printStackTrace();
  96. }
  97. }
  98. /**
  99. * 关闭
  100. */
  101. public void stop() {
  102. this.running = false;
  103. try {
  104. process.destroy();
  105. log.info("关闭媒体流-ffmpeg,{} ", cameraDto.getUrl());
  106. } catch (Exception e) {
  107. process.destroyForcibly();
  108. }
  109. }
  110. /**
  111. * 控制台输出
  112. *
  113. * @param process
  114. */
  115. private void dealStream(Process process) {
  116. if (process == null) {
  117. return;
  118. }
  119. // 处理InputStream的线程
  120. inputThread = new Thread() {
  121. @Override
  122. public void run() {
  123. BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
  124. String line = null;
  125. try {
  126. while (running) {
  127. line = in.readLine();
  128. if (line == null) {
  129. break;
  130. }
  131. if (enableLog) {
  132. log.info("output: " + line);
  133. }
  134. }
  135. } catch (IOException e) {
  136. e.printStackTrace();
  137. } finally {
  138. try {
  139. running = false;
  140. in.close();
  141. } catch (IOException e) {
  142. e.printStackTrace();
  143. }
  144. }
  145. }
  146. };
  147. // 处理ErrorStream的线程
  148. errThread = new Thread() {
  149. @Override
  150. public void run() {
  151. BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  152. String line = null;
  153. try {
  154. while (running) {
  155. line = err.readLine();
  156. if (line == null) {
  157. break;
  158. }
  159. if (enableLog) {
  160. log.info("err: " + line);
  161. }
  162. }
  163. } catch (IOException e) {
  164. e.printStackTrace();
  165. } finally {
  166. try {
  167. running = false;
  168. err.close();
  169. } catch (IOException e) {
  170. e.printStackTrace();
  171. }
  172. }
  173. }
  174. };
  175. inputThread.start();
  176. errThread.start();
  177. }
  178. @Override
  179. public void hasClient() {
  180. }
  181. }