Blame view

src/main/java/com/objecteye/utils/PreviewUtils.java 5.74 KB
c83b5b39   Liu Haoyu   项目创建, 集成spring-se...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
  package com.objecteye.utils;
  
  import org.springframework.stereotype.Component;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.util.concurrent.ConcurrentHashMap;
  
  /**
   * @author 作者
   * @version 创建时间:20181114 下午5:21:18 类说明
   */
  @Component
  public class PreviewUtils {
      /*
       * rtsprtmp指令
       */
      public static String ffmpegTnstructions;
      /**
       * 存放所有rtmp流对应的process进程 keyrtmp value为转流进程
       */
      private static ConcurrentHashMap<String, Process> rtmpAndprocessMaps = new ConcurrentHashMap<>();
      /**
       * 存放用户对应的rtmp key为用户名 valuertmp
       */
      private static ConcurrentHashMap<String, String> userAndrtmpMaps = new ConcurrentHashMap<>();
  
      /**
       * rtsprtmp 得到rtmp
       */
      public static String RtspToRtmp(String serverIp, String rtsp, Integer deviceId, String equipmentUserName,
                                      String equipmentPassWord, String equipmentIp, String port) throws InterruptedException {
          // 转流成功的rtmp流地址
          String rtmpStr = "rtmp://" + serverIp + ":1935/hls/" + deviceId;
          boolean rtmpStrIsVaild = true;
          try {
              // 先判断rtmp流是否存在 存在拿来直接用 不需要转流
              if (rtmpAndprocessMaps.containsKey(rtmpStr)) {
                  // 一个用户只能保存一个rtmp流
  				/*if (userAndrtmpMaps.containsKey(userName)) {
  					userAndrtmpMaps.remove(userName);
  				}
  				userAndrtmpMaps.put(userName, rtmpStr);*/
              } else {
                  Process process = null;
                  if (rtsp.contains("rtsp")) {
                      ffmpegTnstructions = "ffmpeg  -re  -stream_loop -1 -rtsp_transport  tcp -i " + rtsp + " -vcodec copy -acodec copy -f flv -r 15 -s 1280x720 -an -y " + rtmpStr;
                  } else {
                      ffmpegTnstructions = "ffmpeg  -re  -stream_loop -1 -rtsp_transport  tcp -i rtsp://" + equipmentUserName + ":" + equipmentPassWord + "@" + equipmentIp + ":" + port + "/h264/ch1/main/av_stream  -vcodec copy -acodec copy -f flv -r 15 -s 1280x720 -an -y rtmp://" + serverIp + ":1935/hls/" + deviceId;
                  }
                  //System.out.println("运行代码:"+ffmpegTnstructions);
                  try {
                      process = Runtime.getRuntime().exec(ffmpegTnstructions);
                      rtmpAndprocessMaps.put(rtmpStr, process);
                      //userAndrtmpMaps.put(userName, rtmpStr);
                      ManageProcess(process);
                      Thread.sleep(100);
                      rtmpStrIsVaild = process.isAlive();
                      //System.out.println("转流进程是否在运行:" + rtmpStrIsVaild);
  
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
              // 将没有用户在调用的线程 关闭
  			/*for (String rtmpString : rtmpAndprocessMaps.keySet()) {
  				if (!userAndrtmpMaps.containsValue(rtmpString)) {
  					System.out.println("当前转流进程未使用,停止rtsp转rtmp");
  					Process detroyPro = rtmpAndprocessMaps.get(rtmpString);
  					// 先判断进程是否存在
  					if (detroyPro.isAlive()) {
  						detroyPro.destroy();
  					}
  					rtmpAndprocessMaps.remove(rtmpString);
  				}
  			}*/
              // 输出当前内存存在的process和rtmp
  			/*for (String rtmpString : rtmpAndprocessMaps.keySet()) {
  				System.out.println(
  						"rtmpAndprocessMaps存在的值key为:" + rtmpString + " value为:" + rtmpAndprocessMaps.get(rtmpString));
  			}*/
              // 输出当前内存存在的user和rtmp流
  			/*for (String userString : userAndrtmpMaps.keySet()) {
  				System.out.println(
  						"userAndrtmpMaps存在的值key为:" + userString + " value为:" + userAndrtmpMaps.get(userString));
  			}*/
          } catch (Exception e) {
              // TODO: handle exception
              e.printStackTrace();
          }
          if (rtmpStrIsVaild) {
              return rtmpStr;
          } else {
              return null;
          }
      }
  
      /*
       * 输出缓冲流 ----解决一段时间后实时流卡住的问题
       */
      public static void ManageProcess(Process proc) throws IOException, InterruptedException {
          try {
              new Thread(new Runnable() {
                  public void run() {
                      /// 错误输出
                      BufferedReader br2 = null;
                      InputStreamReader is2 = null;
                      try {
                          br2 = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
                          StringBuilder buf = new StringBuilder(); // 保存输出结果流
                          String line2 = null;
                          while ((line2 = br2.readLine()) != null) {
                              buf.append(line2);
                              // 循环等待ffmpeg进程结束
                          }
                      } catch (Exception e) {
                          e.printStackTrace();
                      } finally {
                          if (br2 != null) {
                              try {
                                  br2.close();
                              } catch (Exception ex) {
                              }
                          }
                          if (is2 != null) {
                              try {
                                  is2.close();
                              } catch (IOException e) {
                                  // TODO Auto-generated catch block
                                  e.printStackTrace();
                              }
                          }
                      }
                  }
              }).start();
          } catch (Exception e) {
              // TODO: handle exception
              e.printStackTrace();
          }
      }
  }