diff --git a/WebRoot/WEB-INF/classes/cc/eguid/livepush/PushManager.class b/WebRoot/WEB-INF/classes/cc/eguid/livepush/PushManager.class index 0cb1e109cc85f52ee8e1d8c4781af6493bffc607..b204799f3de27073d8468d32dc2ba3321b059e32 100644 Binary files a/WebRoot/WEB-INF/classes/cc/eguid/livepush/PushManager.class and b/WebRoot/WEB-INF/classes/cc/eguid/livepush/PushManager.class differ diff --git a/WebRoot/WEB-INF/classes/cc/eguid/livepush/PushManagerImpl.class b/WebRoot/WEB-INF/classes/cc/eguid/livepush/PushManagerImpl.class index 78830c64ac5f57deba516cbac3dca62aa461e6bd..6fd339900ccc1b073145ae5a511f0d12797c153d 100644 Binary files a/WebRoot/WEB-INF/classes/cc/eguid/livepush/PushManagerImpl.class and b/WebRoot/WEB-INF/classes/cc/eguid/livepush/PushManagerImpl.class differ diff --git a/WebRoot/WEB-INF/classes/cc/eguid/livepush/Readme b/WebRoot/WEB-INF/classes/cc/eguid/livepush/Readme index 5c567668076f02d2142d1f1863e9accdbaa076e8..701d76bb7a6d37853fefa818fe5d62cbaf680f3e 100644 --- a/WebRoot/WEB-INF/classes/cc/eguid/livepush/Readme +++ b/WebRoot/WEB-INF/classes/cc/eguid/livepush/Readme @@ -1,4 +1,4 @@ -使用说明: +livePush0.2.1使用说明: (重要:使用前必须保证ffmpeg环境包在该项目的WEB-INF\classes\cc\eguid\livepush\ffmpeg\目录中) 1、对象创建 PushManager pusher = new PushManagerImpl(); @@ -8,19 +8,21 @@ PushManager pusher = new PushManagerImpl(); name:应用名; input:接收地址; output:推送地址; +codec:视频编码; fmt:视频格式; fps:视频帧率; rs:视频分辨率; -disableAudio:是否开启音频; +twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码) 2.2、参数使用 Map map = new HashMap(); map.put("appName", "testwanglaing123"); map.put("input","rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0"); map.put("output", "rtmp://192.168.30.21/live/"); +map.put("codec","h264"); map.put("fmt", "flv"); map.put("fps", "25"); map.put("rs", "640x360"); -map.put("disableAudio", "true"); +map.put("twoPart","2"); 3、调用方法 3.1、发布方法 diff --git a/WebRoot/WEB-INF/classes/cc/eguid/livepush/conf/ConfUtil.class b/WebRoot/WEB-INF/classes/cc/eguid/livepush/conf/ConfUtil.class index 6c6975fd20277b6a2ac2ada087e16e5c116206f0..4f1e31a5555629d78d29ce13cf4327634e4f9346 100644 Binary files a/WebRoot/WEB-INF/classes/cc/eguid/livepush/conf/ConfUtil.class and b/WebRoot/WEB-INF/classes/cc/eguid/livepush/conf/ConfUtil.class differ diff --git a/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/OutHandler.class b/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/OutHandler.class index e7990acb8e6916643af3f5c3a9e591849ff2b8d2..7f26c0e3ecac632ec894f58dc9f3eb0d1011ce41 100644 Binary files a/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/OutHandler.class and b/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/OutHandler.class differ diff --git a/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/PushHandler.class b/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/PushHandler.class index 4c2d6bcafd03a3dfb630ce62dcfd7a0983d35570..110759bd3c870176e85f8ade53de96c14a493637 100644 Binary files a/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/PushHandler.class and b/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/PushHandler.class differ diff --git a/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/PushHandlerImpl.class b/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/PushHandlerImpl.class index ce148d64a1efa2ae7afbe5c6786d42ca96ae4773..e5da1a2bd0d8cf5f0bb59ba8efd3ad6ad6b7114c 100644 Binary files a/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/PushHandlerImpl.class and b/WebRoot/WEB-INF/classes/cc/eguid/livepush/handler/PushHandlerImpl.class differ diff --git a/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/entity/LiveInfoEntity.class b/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/entity/LiveInfoEntity.class index d980978a5373a13a31781c9b47b6b298e92d69ad..96d8ab06bf3917be39f1d0093bfba22fbba6cbb2 100644 Binary files a/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/entity/LiveInfoEntity.class and b/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/entity/LiveInfoEntity.class differ diff --git a/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/entity/ResultData.class b/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/entity/ResultData.class index 7dcb5eb05c2a5b8b827fb3145351868f58a6a632..66c99a5c44a3c6eedbfbed514344a82e0da2e6d9 100644 Binary files a/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/entity/ResultData.class and b/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/entity/ResultData.class differ diff --git a/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/service/CameraLiveServiceImpl.class b/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/service/CameraLiveServiceImpl.class index 44ea3bb7124c06eae474b8084fb51e6d7ebd5a30..04c1aa1eea2efe8b96b4caeace4a7836680d8071 100644 Binary files a/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/service/CameraLiveServiceImpl.class and b/WebRoot/WEB-INF/classes/cn/njlingdong/cameraLive/service/CameraLiveServiceImpl.class differ diff --git a/classes/cc/eguid/livepush/PushManager.java b/classes/cc/eguid/livepush/PushManager.java index f7c877e006cad167bb3cfc40bec37297658fc515..96bb436c70e52bc9b2ff31142ef546700ebd3c11 100644 --- a/classes/cc/eguid/livepush/PushManager.java +++ b/classes/cc/eguid/livepush/PushManager.java @@ -25,7 +25,7 @@ public interface PushManager * @param map * @return pushId(当前发布流的标识,方便操作该push) */ -public String push(Mapmap); +public String push(Mapmap); /** * 通过应用名删除某个push * @param pushId diff --git a/classes/cc/eguid/livepush/PushManagerImpl.java b/classes/cc/eguid/livepush/PushManagerImpl.java index a0e7c931a96edb0d762bc5165af83f61d059f7d4..916c5e9700cb0fe225e8c99d8028527b06e4fe4e 100644 --- a/classes/cc/eguid/livepush/PushManagerImpl.java +++ b/classes/cc/eguid/livepush/PushManagerImpl.java @@ -14,7 +14,6 @@ import cc.eguid.livepush.handler.OutHandler; import cc.eguid.livepush.handler.PushHandler; import cc.eguid.livepush.handler.PushHandlerImpl; - /** * 实现push管理器的push,delete,view服务 * @@ -24,106 +23,91 @@ import cc.eguid.livepush.handler.PushHandlerImpl; * @since jdk1.7 */ -public class PushManagerImpl implements PushManager -{ - /** - *配置文件 - */ - private ConfUtil confUtil = new ConfUtil(); - - public PushManagerImpl() - { - confUtil.isHave(); - } - - /** - * 引用push处理器 - */ - private PushHandler pusher = new PushHandlerImpl(); - - /** - * 管理处理器的主进程Process及两个输出线程的关系 - */ - private HandlerDao hd = new HandlerDaoImpl(); - - public void setPusher(PushHandler pusher) - { - this.pusher = pusher; - } - - public void setHd(HandlerDao hd) - { - this.hd = hd; - } - - @Override - public String push(Map parammap) - { - // ffmpeg环境是否配置正确 - if (!confUtil.isHave()) - { - return null; - } - - // 参数是否符合要求 - if (parammap == null || parammap.isEmpty() || !parammap.containsKey("appName")) - { - return null; - } - String appName = null; - ConcurrentMap resultMap = null; - try - { - appName = parammap.get("appName"); - if (appName != null && "".equals(appName.trim())) - { - return null; - } - parammap.put("ffmpegPath", confUtil.getPath()); - resultMap = pusher.push(parammap); - // 处理器和输出线程对应关系 - hd.set(appName, resultMap); - } - catch (Exception e) - { - // 暂时先写这样,后期加日志 - System.err.println("重大错误:参数不符合要求" + e.getMessage()); - } - return appName; - - } - - @Override - public boolean closePush(String appName) - { - if (hd.isHave(appName)) - { - ConcurrentMap map = hd.get(appName); - // 关闭两个线程 - ((OutHandler)map.get("error")).destroy(); - // ((OutHandler)map.get("info")).destroy(); - // 暂时先这样写,后期加日志 - System.out.println("停止命令-----end commond"); - // 关闭命令主进程 - ((Process)map.get("process")).destroy(); - // 删除处理器与线程对应关系表 - hd.delete(appName); - return true; - } - return false; - } - - @Override - public Set viewAppName() - { - return hd.getAllAppName(); - } - - @Override - public boolean isHave(String appName) - { - hd.isHave(appName); - return false; - - } +public class PushManagerImpl implements PushManager { + /** + * 配置文件 + */ + private ConfUtil confUtil = new ConfUtil(); + + public PushManagerImpl() { + confUtil.isHave(); + } + + /** + * 引用push处理器 + */ + private PushHandler pusher = new PushHandlerImpl(); + + /** + * 管理处理器的主进程Process及两个输出线程的关系 + */ + private HandlerDao hd = new HandlerDaoImpl(); + + public synchronized void setPusher(PushHandler pusher) { + this.pusher = pusher; + } + + public synchronized void setHd(HandlerDao hd) { + this.hd = hd; + } + + @Override + public synchronized String push(Map parammap) { + String appName = null; + ConcurrentMap resultMap = null; + try { + // ffmpeg环境是否配置正确 + if (!confUtil.isHave()) { + return null; + } + // 参数是否符合要求 + if (parammap == null || parammap.isEmpty() || !parammap.containsKey("appName")) { + return null; + } + appName = (String) parammap.get("appName"); + if (appName != null && "".equals(appName.trim())) { + return null; + } + parammap.put("ffmpegPath", confUtil.getPath()); + resultMap = pusher.push(parammap); + // 处理器和输出线程对应关系 + hd.set(appName, resultMap); + } catch (Exception e) { + // 暂时先写这样,后期加日志 + System.err.println("重大错误:参数不符合要求或运行失败" + e.getMessage()); + return null; + } + return appName; + + } + + @Override + public synchronized boolean closePush(String appName) { + if (hd.isHave(appName)) { + ConcurrentMap map = hd.get(appName); + // 关闭两个线程 + ((OutHandler) map.get("error")).destroy(); + // ((OutHandler)map.get("info")).destroy(); + // 暂时先这样写,后期加日志 + System.out.println("停止命令-----end commond"); + // 关闭命令主进程 + ((Process) map.get("process")).destroy(); + // 删除处理器与线程对应关系表 + hd.delete(appName); + return true; + } + return false; + } + + @Override + public synchronized Set viewAppName() { + return hd.getAllAppName(); + } + + @Override + public synchronized boolean isHave(String appName) { + hd.isHave(appName); + return false; + + } } diff --git a/classes/cc/eguid/livepush/Readme b/classes/cc/eguid/livepush/Readme index 5c567668076f02d2142d1f1863e9accdbaa076e8..701d76bb7a6d37853fefa818fe5d62cbaf680f3e 100644 --- a/classes/cc/eguid/livepush/Readme +++ b/classes/cc/eguid/livepush/Readme @@ -1,4 +1,4 @@ -使用说明: +livePush0.2.1使用说明: (重要:使用前必须保证ffmpeg环境包在该项目的WEB-INF\classes\cc\eguid\livepush\ffmpeg\目录中) 1、对象创建 PushManager pusher = new PushManagerImpl(); @@ -8,19 +8,21 @@ PushManager pusher = new PushManagerImpl(); name:应用名; input:接收地址; output:推送地址; +codec:视频编码; fmt:视频格式; fps:视频帧率; rs:视频分辨率; -disableAudio:是否开启音频; +twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码) 2.2、参数使用 Map map = new HashMap(); map.put("appName", "testwanglaing123"); map.put("input","rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0"); map.put("output", "rtmp://192.168.30.21/live/"); +map.put("codec","h264"); map.put("fmt", "flv"); map.put("fps", "25"); map.put("rs", "640x360"); -map.put("disableAudio", "true"); +map.put("twoPart","2"); 3、调用方法 3.1、发布方法 diff --git a/classes/cc/eguid/livepush/conf/ConfUtil.java b/classes/cc/eguid/livepush/conf/ConfUtil.java index cf90c0c23c244e7cfcff32e98389351e5851dabf..350c4c8e7ec7e9dcc503317c4e53662f16d74b39 100644 --- a/classes/cc/eguid/livepush/conf/ConfUtil.java +++ b/classes/cc/eguid/livepush/conf/ConfUtil.java @@ -29,8 +29,9 @@ public class ConfUtil */ private void initConfInfo() { - System.out.print("预加载配置:"); + String path = getClass().getResource("../").getPath() + "ffmpeg/ffmpeg.exe"; + System.out.print("预加载FFMPEG配置:"+path); File ffmpeg =new File(path); ffmpegPath=ffmpeg.getPath(); if (isHave=ffmpeg.isFile()) diff --git a/classes/cc/eguid/livepush/handler/OutHandler.java b/classes/cc/eguid/livepush/handler/OutHandler.java index ad2bbec359f4aedea811c0bf98f2d86f69f8f2d7..6da9c2e90647aed5000499a388f8b1b085ef332b 100644 --- a/classes/cc/eguid/livepush/handler/OutHandler.java +++ b/classes/cc/eguid/livepush/handler/OutHandler.java @@ -3,13 +3,11 @@ */ package cc.eguid.livepush.handler; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; - /** * 用于输出命令行主进程的消息线程(必须开启,否则命令行主进程无法正常执行) 重要:该类重写了destroy方法,用于安全的关闭该线程 * @@ -19,92 +17,71 @@ import java.io.InputStreamReader; * @since jdk1.7 */ -public class OutHandler extends Thread -{ - /** - * 控制状态 - */ - private volatile boolean desstatus = true; +public class OutHandler extends Thread { + /** + * 控制状态 + */ + private volatile boolean desstatus = true; + + /** + * 读取输出流 + */ + private BufferedReader br = null; + + /** + * 输出类型 + */ + private String type = null; - /** - * 读取输出流 - */ - private BufferedReader br=null; + public OutHandler(InputStream is, String type) { + br = new BufferedReader(new InputStreamReader(is)); + this.type = type; + } - /** - * 输出类型 - */ - private String type=null; + /** + * 重写线程销毁方法,安全的关闭线程 + */ + @Override + public void destroy() { + setDesStatus(false); + } - public OutHandler(InputStream is, String type) - { - br = new BufferedReader(new InputStreamReader(is)); - this.type = type; - } + public void setDesStatus(boolean desStatus) { + this.desstatus = desStatus; + } - /** - * 重写线程销毁方法,安全的关闭线程 - */ - @Override - public void destroy() - { - setDesStatus(false); - } - - public void setDesStatus(boolean desStatus) - { - this.desstatus = desStatus; - } + /** + * 执行输出线程 + */ + @Override + public void run() { + String msg = null; + int index = 0; + int errorIndex = 0; + int status = 10; + try { + System.out.println(type + "开始推流!"); + while (desstatus && (msg = br.readLine()) != null) { + if (msg.indexOf("[rtsp") != -1) { + System.out.println("接收" + status + "个数据包" + msg); + System.out.println(type + ",网络异常丢包,丢包次数:" + errorIndex++ + ",消息体:" + msg); + status = 10; + index = 0; + } - /** - * 执行输出线程 - */ - @Override - public void run() - { - String msg = null; - int status = 0; - int index = 0; - try - { - while (desstatus&&(msg = br.readLine()) != null) - { - if (msg.indexOf("[rtsp") != -1) - { - if (status > 5) - { - System.err.println(type + "持续发生严重网络丢包错误,建议立即关闭该应用后检查网络状况!"); - } - else - { - System.out.println(type + ",网络异常丢包:" + msg); - } - status++ ; - } - else if (msg.indexOf("[h264") != -1) - { - System.out.println(type + ",解码错误:" + msg); - } - else - { - if (index >= 10) - { - System.out.println(type + ",网络消息:接收到" + index + "个数据包"); - index = 0; - } - index++ ; - } - } - } - catch (IOException e) - { - System.out.println("发生内部异常错误,自动关闭["+this.getId()+"]线程"); - destroy(); - }finally { - if(this.isAlive()) - { - destroy(); - } - } - } + if (index % status == 0) { + System.out.println("接收" + status + "个数据包" + msg); + status *= 2; + } + index++; + } + } catch (IOException e) { + System.out.println("发生内部异常错误,自动关闭[" + this.getId() + "]线程"); + destroy(); + } finally { + if (this.isAlive()) { + destroy(); + } + } + } } diff --git a/classes/cc/eguid/livepush/handler/PushHandler.java b/classes/cc/eguid/livepush/handler/PushHandler.java index 6443c50adb6690b96fde7a4f90766242ea08f08a..f37a2744242fb4643d471b2203b3179922c8c1b2 100644 --- a/classes/cc/eguid/livepush/handler/PushHandler.java +++ b/classes/cc/eguid/livepush/handler/PushHandler.java @@ -23,12 +23,12 @@ public interface PushHandler { /** * 处理push操作(包含一个主进程和两个输出线程) - * @param map + * @param parammap * 格式: * name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率;disableAudio:是否开启音频 * @return map(进程,消息(info,error)) * @throws IOException * */ -public ConcurrentMap push(Mapmap)throws Exception; +public ConcurrentMap push(Map parammap)throws Exception; } diff --git a/classes/cc/eguid/livepush/handler/PushHandlerImpl.java b/classes/cc/eguid/livepush/handler/PushHandlerImpl.java index c1382a0f46b9bdf4041d12a388d300884d86c035..15f3bf44dc7cc0d472c945c7365da68fa366574e 100644 --- a/classes/cc/eguid/livepush/handler/PushHandlerImpl.java +++ b/classes/cc/eguid/livepush/handler/PushHandlerImpl.java @@ -16,78 +16,111 @@ import java.util.concurrent.ConcurrentMap; * @since jdk1.7 */ -public class PushHandlerImpl implements PushHandler -{ - /* - * "ffmpeg -i "+ "rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0 "+ - * " -f flv -r 25 -s 640x360 -an" + " rtmp://192.168.30.21/live/test" 推送流格式: - * name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率;disableAudio:是否开启音频 - */ - @Override - public ConcurrentMap push(Map paramMap) - throws Exception - { - // 从map里面取数据,组装成命令 - String comm = getComm4Map(paramMap); - ConcurrentMap resultMap = null; - // 执行命令行 - System.out.println("执行命令----start commond:" + comm); - final Process proc = Runtime.getRuntime().exec(comm); - OutHandler errorGobbler = new OutHandler(proc.getErrorStream(), paramMap.get("appName")); - // OutHandler outputGobbler = new OutHandler(proc.getInputStream(), "Info"); +public class PushHandlerImpl implements PushHandler { + + @Override + public ConcurrentMap push(Map paramMap) throws Exception { + ConcurrentMap resultMap = null; + Process proc =null; + OutHandler errorGobbler=null; + try{ + // 从map里面取数据,组装成命令 + String comm = getComm4Map(paramMap); + if(comm==null) + { + throw new Exception(); + } + // 执行命令行 + System.out.println("执行命令:" + comm); + proc = Runtime.getRuntime().exec(comm); + + errorGobbler = new OutHandler(proc.getErrorStream(), (String) paramMap.get("appName")); + errorGobbler.start(); + + // 返回参数 + resultMap = new ConcurrentHashMap(); + // resultMap.put("info", outputGobbler); + resultMap.put("error", errorGobbler); + resultMap.put("process", proc); + }catch(Exception e){ + if(proc!=null){ + proc.destroy(); + } + if(errorGobbler!=null){ + errorGobbler.destroy(); + } + throw e; + } + return resultMap; + } - errorGobbler.start(); - // outputGobbler.start(); - // 返回参数 - resultMap = new ConcurrentHashMap(); - // resultMap.put("info", outputGobbler); - resultMap.put("error", errorGobbler); - resultMap.put("process", proc); - return resultMap; - } - - /** - * 通过解析参数生成可执行的命令行字符串; - * name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率;disableAudio:是否开启音频 - * - * @param paramMap - * @throws Exception - * @return 命令行字符串 - */ - protected String getComm4Map(Map paramMap) throws Exception - { - - if (paramMap.containsKey("ffmpegPath")) - { - StringBuilder comm = new StringBuilder(paramMap.get("ffmpegPath") + " -i "); - // -i:输入流地址或者文件绝对地址 - - // 是否有必输项:输入地址,输出地址,应用名 - if (paramMap.containsKey("input") && paramMap.containsKey("output") - && paramMap.containsKey("appName")) - { - comm.append(paramMap.get("input")).append(" "); - // -f :转换格式,默认flv - comm.append(" -f ").append(paramMap.containsKey("fmt") ? paramMap.get("fmt") : "flv").append(" "); - // -r :帧率,默认25 - comm.append("-r ").append(paramMap.containsKey("fps") ? paramMap.get("fps") : "30").append(" "); - // -s 分辨率 默认是原分辨率 - comm.append("-s ").append(paramMap.containsKey("rs") ? paramMap.get("rs") : "").append(" "); - // -an 禁用音频 - comm.append("-an ").append(paramMap.containsKey("disableAudio") && ("true".equals(paramMap.get("disableAudio"))) ? "-an" : "").append(" "); - // 输出地址 - comm.append(paramMap.get("output")); - // 发布的应用名 - comm.append(paramMap.get("appName")); - // 一个视频源,可以有多个输出,第二个输出为拷贝源视频输出,不改变视频的各项参数并且命名为应用名+HD - comm.append(" ").append(" -vcodec copy -f flv -an ").append(paramMap.get("output")).append(paramMap.get("appName")).append("HD"); - return comm.toString(); - } - } - else - { - throw new Exception("重大错误:必输项不能为空!"); - } - return null; - } + /* + * "ffmpeg -i "+ + * "rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0 " + * + " -f flv -r 25 -s 640x360 -an" + " rtmp://192.168.30.21/live/test" + * 推送流格式: + * name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率 + * 是否开启音频 + */ + /** + * 通过解析参数生成可执行的命令行字符串; + * name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率 + * "ffmpeg -i rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0 -f flv -r 25 -s 640x360 -an rtmp://192.168.30.21/live/test" + * @param paramMap + * @throws Exception + * @return 命令行字符串 + */ + protected String getComm4Map(Map paramMap) throws Exception{ + try{ + if (paramMap.containsKey("ffmpegPath")) { + String ffmpegPath = (String) paramMap.get("ffmpegPath"); + // -i:输入流地址或者文件绝对地址 + StringBuilder comm = new StringBuilder(ffmpegPath + " -i "); + // 是否有必输项:输入地址,输出地址,应用名,twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码) + if (paramMap.containsKey("input") && paramMap.containsKey("output") && paramMap.containsKey("appName")&& paramMap.containsKey("twoPart")) { + String input = (String) paramMap.get("input"); + String output = (String) paramMap.get("output"); + String appName = (String) paramMap.get("appName"); + String twoPart = (String) paramMap.get("twoPart"); + String codec=(String) paramMap.get("codec"); + //默认h264解码 + codec=(codec==null?"h264":(String) paramMap.get("codec")); + // 输入地址 + comm.append(input); + // 当twoPart为0时,只推一个元码流 + if ("0".equals(twoPart)) { + comm.append(" -vcodec "+codec+" -f flv -an "+output + appName); + }else{ + // -f :转换格式,默认flv + if (paramMap.containsKey("fmt")) { + String fmt = (String) paramMap.get("fmt"); + comm.append(" -f " + fmt); + } + // -r :帧率,默认25;-g :帧间隔 + if (paramMap.containsKey("fps")) { + String fps = (String) paramMap.get("fps"); + comm.append(" -r " + fps); + comm.append(" -g " + fps); + } + // -s 分辨率 默认是原分辨率 + if (paramMap.containsKey("rs")) { + String rs = (String) paramMap.get("rs"); + comm.append(" -s " + rs); + } + // 输出地址+发布的应用名 + comm.append(" -an "+output + appName); + // 当twoPart为2时推两个流,一个自定义流,一个元码流 + if ("2".equals(twoPart)) { + // 一个视频源,可以有多个输出,第二个输出为拷贝源视频输出,不改变视频的各项参数并且命名为应用名+HD + comm.append(" -vcodec copy -f flv -an ").append(output +appName+ "HD"); + } + } + return comm.toString(); + } + } + }catch(Exception e){ + throw e; + } + return null; + } } diff --git a/classes/cn/njlingdong/cameraLive/entity/LiveInfoEntity.java b/classes/cn/njlingdong/cameraLive/entity/LiveInfoEntity.java index 6c087502f4ea971b16b57131f15c832841596ef7..9671c9e41b3798dbdfc5682eacffc60a8905309e 100644 --- a/classes/cn/njlingdong/cameraLive/entity/LiveInfoEntity.java +++ b/classes/cn/njlingdong/cameraLive/entity/LiveInfoEntity.java @@ -13,190 +13,174 @@ import java.io.Serializable; * @see LiveInfoEntity * @since jdk1.7 */ -public class LiveInfoEntity implements Serializable -{ - - public LiveInfoEntity() - { - super(); - } - - public LiveInfoEntity(String appName, String input, String output, String fmt, String fps, - String rs, String disableAudio) - { - super(); - this.appName = appName; - this.input = input; - this.output = output; - this.fmt = fmt; - this.fps = fps; - this.rs = rs; - this.disableAudio = disableAudio; - } - - /** - * 应用名 - */ - private String appName; - - /** - * 视频源地址,可以是实时流地址也可以是文件路径 - */ - private String input; - - /** - * 实时流输出地址,这个默认是固定的rtmp服务器发布地址 - */ - private String output; - - /** - * 视频格式,默认flv - */ - private String fmt; - - /** - * 帧率,最好是25-60 - */ - private String fps; - - /** - * 分辨率,例如:640x360 - */ - private String rs; - - /** - * 是否关闭音频 - */ - private String disableAudio; - - /** - * @return the appName - */ - public String getAppName() - { - return appName; - } - - /** - * @param appName - * the appName to set - */ - public void setAppName(String appName) - { - this.appName = appName; - } - - /** - * @return the input - */ - public String getInput() - { - return input; - } - - /** - * @param input - * the input to set - */ - public void setInput(String input) - { - this.input = input; - } - - /** - * @return the output - */ - public String getOutput() - { - return output; - } - - /** - * @param output - * the output to set - */ - public void setOutput(String output) - { - this.output = output; - } - - /** - * @return the fmt - */ - public String getFmt() - { - return fmt; - } - - /** - * @param fmt - * the fmt to set - */ - public void setFmt(String fmt) - { - this.fmt = fmt; - } - - /** - * @return the fps - */ - public String getFps() - { - return fps; - } - - /** - * @param fps - * the fps to set - */ - public void setFps(String fps) - { - this.fps = fps; - } - - /** - * @return the rs - */ - public String getRs() - { - return rs; - } - - /** - * @param rs - * the rs to set - */ - public void setRs(String rs) - { - this.rs = rs; - } - - /** - * @return the disableAudio - */ - public String getDisableAudio() - { - return disableAudio; - } - - /** - * @param disableAudio - * the disableAudio to set - */ - public void setDisableAudio(String disableAudio) - { - this.disableAudio = disableAudio; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() - { - return "LiveInfoEntity [appName=" + appName + ", input=" + input + ", output=" + output - + ", fmt=" + fmt + ", fps=" + fps + ", rs=" + rs + ", disableAudio=" + disableAudio - + "]"; - } +public class LiveInfoEntity implements Serializable { + private static final long serialVersionUID = -2657813061488195041L; + + public LiveInfoEntity() { + super(); + } + + public LiveInfoEntity(String appName, String input, String output, String fmt, String fps, String rs, + String disableAudio) { + super(); + this.appName = appName; + this.input = input; + this.output = output; + this.fmt = fmt; + this.fps = fps; + this.rs = rs; + this.disableAudio = disableAudio; + } + + /** + * 应用名 + */ + private String appName; + + /** + * 视频源地址,可以是实时流地址也可以是文件路径 + */ + private String input; + + /** + * 实时流输出地址,这个默认是固定的rtmp服务器发布地址 + */ + private String output; + + /** + * 视频格式,默认flv + */ + private String fmt; + + /** + * 帧率,最好是25-60 + */ + private String fps; + + /** + * 分辨率,例如:640x360 + */ + private String rs; + + /** + * 是否关闭音频 + */ + private String disableAudio; + + /** + * @return the appName + */ + public String getAppName() { + return appName; + } + + /** + * @param appName + * the appName to set + */ + public void setAppName(String appName) { + this.appName = appName; + } + + /** + * @return the input + */ + public String getInput() { + return input; + } + + /** + * @param input + * the input to set + */ + public void setInput(String input) { + this.input = input; + } + + /** + * @return the output + */ + public String getOutput() { + return output; + } + + /** + * @param output + * the output to set + */ + public void setOutput(String output) { + this.output = output; + } + + /** + * @return the fmt + */ + public String getFmt() { + return fmt; + } + + /** + * @param fmt + * the fmt to set + */ + public void setFmt(String fmt) { + this.fmt = fmt; + } + + /** + * @return the fps + */ + public String getFps() { + return fps; + } + + /** + * @param fps + * the fps to set + */ + public void setFps(String fps) { + this.fps = fps; + } + + /** + * @return the rs + */ + public String getRs() { + return rs; + } + + /** + * @param rs + * the rs to set + */ + public void setRs(String rs) { + this.rs = rs; + } + + /** + * @return the disableAudio + */ + public String getDisableAudio() { + return disableAudio; + } + + /** + * @param disableAudio + * the disableAudio to set + */ + public void setDisableAudio(String disableAudio) { + this.disableAudio = disableAudio; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "LiveInfoEntity [appName=" + appName + ", input=" + input + ", output=" + output + ", fmt=" + fmt + + ", fps=" + fps + ", rs=" + rs + ", disableAudio=" + disableAudio + "]"; + } } diff --git a/classes/cn/njlingdong/cameraLive/entity/ResultData.java b/classes/cn/njlingdong/cameraLive/entity/ResultData.java index 7775fcc2141dcaa4cc2bf4d7644625ca1311618a..75021f6659cab74c1ed46245620b39cb18f98172 100644 --- a/classes/cn/njlingdong/cameraLive/entity/ResultData.java +++ b/classes/cn/njlingdong/cameraLive/entity/ResultData.java @@ -11,51 +11,46 @@ import java.io.Serializable; /** * 响应JSON结果集 - * @author eguid - * @version 2016年6月30日 - * @see ResultData - * @since + * + * @author eguid + * @version 2016年6月30日 + * @see ResultData + * @since */ -public class ResultData implements Serializable -{ -private String status; -private String msg; -private Object data; +public class ResultData implements Serializable { + private static final long serialVersionUID = 7219235230800863548L; + private String status; + private String msg; + private Object data; -public String getStatus() -{ - return status; -} + public String getStatus() { + return status; + } -public void setStatus(String status) -{ - this.status = status; -} + public void setStatus(String status) { + this.status = status; + } -public String getMsg() -{ - return msg; -} + public String getMsg() { + return msg; + } -public void setMsg(String msg) -{ - this.msg = msg; -} + public void setMsg(String msg) { + this.msg = msg; + } -public Object getData() -{ - return data; -} + public Object getData() { + return data; + } -public void setData(Object data) -{ - this.data = data; -} -@Override -public String toString() -{ - return "ResultData [status=" + status + ", msg=" + msg + ", data=" + data + "]"; -} + public void setData(Object data) { + this.data = data; + } + + @Override + public String toString() { + return "ResultData [status=" + status + ", msg=" + msg + ", data=" + data + "]"; + } } diff --git a/classes/cn/njlingdong/cameraLive/service/CameraLiveServiceImpl.java b/classes/cn/njlingdong/cameraLive/service/CameraLiveServiceImpl.java index 52a7d27d9b49cdfab84e9b7d914ba2df3384d5fe..a85f59cc2ce2d1703cd9728ea07e9b529e6bd694 100644 --- a/classes/cn/njlingdong/cameraLive/service/CameraLiveServiceImpl.java +++ b/classes/cn/njlingdong/cameraLive/service/CameraLiveServiceImpl.java @@ -64,7 +64,7 @@ public class CameraLiveServiceImpl implements CameraLiveService } else { - Map map = getMap4LiveInfo(liveInfo); + Map map = getMap4LiveInfo(liveInfo); //开启推送处理器 appName = pusher.push(map); // 存放信息 @@ -90,7 +90,7 @@ public class CameraLiveServiceImpl implements CameraLiveService * @param liveInfo * @return */ - private Map getMap4LiveInfo(LiveInfoEntity liveInfo) + private Map getMap4LiveInfo(LiveInfoEntity liveInfo) { String appName = liveInfo.getAppName(); String input = liveInfo.getInput(); @@ -100,7 +100,7 @@ public class CameraLiveServiceImpl implements CameraLiveService String rs = liveInfo.getRs(); String disableAudio = liveInfo.getDisableAudio(); - Map map = new HashMap(20); + Map map = new HashMap(20); map.put("appName", appName); // 输入输出暂时固定 map.put("input", input);