├── .classpath ├── .project ├── README.md ├── bin └── cc │ └── eguid │ └── livepush │ ├── PushManager.class │ ├── PushManagerImpl.class │ ├── Readme │ ├── conf │ └── ConfUtil.class │ ├── dao │ ├── HandlerDao.class │ └── HandlerDaoImpl.class │ ├── entity │ └── LivePushEntity.class │ ├── ffmpeg │ ├── avcodec-57.dll │ ├── avdevice-57.dll │ ├── avfilter-6.dll │ ├── avformat-57.dll │ ├── avutil-55.dll │ ├── ffmpeg.exe │ ├── ffplay.exe │ ├── ffprobe.exe │ ├── postproc-54.dll │ ├── swresample-2.dll │ └── swscale-4.dll │ └── handler │ ├── OutHandler.class │ ├── PushHandler.class │ └── PushHandlerImpl.class └── src └── cc └── eguid └── livepush ├── PushManager.java ├── PushManagerImpl.java ├── Readme ├── conf └── ConfUtil.java ├── dao ├── HandlerDao.java └── HandlerDaoImpl.java ├── entity └── LivePushEntity.java ├── ffmpeg ├── avcodec-57.dll ├── avdevice-57.dll ├── avfilter-6.dll ├── avformat-57.dll ├── avutil-55.dll ├── ffmpeg.exe ├── ffplay.exe ├── ffprobe.exe ├── postproc-54.dll ├── swresample-2.dll └── swscale-4.dll └── handler ├── OutHandler.java ├── PushHandler.java └── PushHandlerImpl.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | livePush 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # livePush 2 | 一个基于FFMPEG命令封装的简单java推流器(该版本不再更新) 3 | ##由于新版本推翻了原版重新进行了核心功能实现以及全面实现接口化,所以单独建了一个项目以示区别:新版本地址:https://github.com/eguid/FFmpegCommandHandler4java 4 | -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/PushManager.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/PushManager.class -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/PushManagerImpl.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/PushManagerImpl.class -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/Readme: -------------------------------------------------------------------------------- 1 | livePush0.2.1使用说明: 2 | (重要:使用前必须保证ffmpeg环境包在该项目的WEB-INF\classes\cc\eguid\livepush\ffmpeg\目录中) 3 | 1、对象创建 4 | PushManager pusher = new PushManagerImpl(); 5 | 6 | 2、参数说明及设置 7 | 2.1、参数说明 8 | name:应用名; 9 | input:接收地址; 10 | output:推送地址; 11 | codec:视频编码; 12 | fmt:视频格式; 13 | fps:视频帧率; 14 | rs:视频分辨率; 15 | twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码) 16 | 2.2、参数使用 17 | Map map = new HashMap(); 18 | map.put("appName", "testwanglaing123"); 19 | map.put("input","rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0"); 20 | map.put("output", "rtmp://192.168.30.21/live/"); 21 | map.put("codec","h264"); 22 | map.put("fmt", "flv"); 23 | map.put("fps", "25"); 24 | map.put("rs", "640x360"); 25 | map.put("twoPart","2"); 26 | 27 | 3、调用方法 28 | 3.1、发布方法 29 | id push(map) 30 | pusher.push(map); 31 | 32 | 3.2、关闭发布方法 33 | void closePush(appName) 34 | pusher.closePush(appName); 35 | 36 | 3.3、查看所有正在push的列表 37 | Set viewAppName() 38 | pusher.viewAppName(); 39 | 40 | 3.4、检测是否存在某个push 41 | boolean isHave(String appName) 42 | pusher.isHave(appName); -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/conf/ConfUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/conf/ConfUtil.class -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/dao/HandlerDao.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/dao/HandlerDao.class -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/dao/HandlerDaoImpl.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/dao/HandlerDaoImpl.class -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/entity/LivePushEntity.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/entity/LivePushEntity.class -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/avcodec-57.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/avcodec-57.dll -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/avdevice-57.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/avdevice-57.dll -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/avfilter-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/avfilter-6.dll -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/avformat-57.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/avformat-57.dll -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/avutil-55.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/avutil-55.dll -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/ffmpeg.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/ffmpeg.exe -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/ffplay.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/ffplay.exe -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/ffprobe.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/ffprobe.exe -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/postproc-54.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/postproc-54.dll -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/swresample-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/swresample-2.dll -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/ffmpeg/swscale-4.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/ffmpeg/swscale-4.dll -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/handler/OutHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/handler/OutHandler.class -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/handler/PushHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/handler/PushHandler.class -------------------------------------------------------------------------------- /bin/cc/eguid/livepush/handler/PushHandlerImpl.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/bin/cc/eguid/livepush/handler/PushHandlerImpl.class -------------------------------------------------------------------------------- /src/cc/eguid/livepush/PushManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 文件名:PushManager.java 3 | * 描述:用于处理push相关操作的接口 4 | * 修改人:eguid 5 | * 修改时间:2016年6月24日 6 | * 修改内容: 7 | */ 8 | package cc.eguid.livepush; 9 | 10 | import java.util.Map; 11 | import java.util.Set; 12 | 13 | /** 14 | * 用于提供push操作的增删查服务 15 | * @author eguid 16 | * @version 2016年6月24日 17 | * @see PushManager 18 | * @since jdk1.7 19 | */ 20 | 21 | public interface PushManager 22 | { 23 | /** 24 | * 发布一个流到服务器 25 | * @param map 26 | * @return pushId(当前发布流的标识,方便操作该push) 27 | */ 28 | public String push(Mapmap); 29 | /** 30 | * 通过应用名删除某个push 31 | * @param pushId 32 | */ 33 | public boolean closePush(String appName); 34 | /** 35 | * 查看全部当前正在运行的应用名称 36 | * @param pushId 37 | */ 38 | public Set viewAppName(); 39 | /** 40 | * 应用是否已经存在 41 | * @param appName 42 | * @return true:存在;false:不存在 43 | */ 44 | public boolean isHave(String appName); 45 | } 46 | -------------------------------------------------------------------------------- /src/cc/eguid/livepush/PushManagerImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 文件名:PushMangerImpl.java 描述:实现push管理器的接口功能 修改人:eguid 修改时间:2016年6月29日 修改内容:增加管理处理器和应用名关系 3 | */ 4 | package cc.eguid.livepush; 5 | 6 | import java.util.Map; 7 | import java.util.Set; 8 | import java.util.concurrent.ConcurrentMap; 9 | 10 | import cc.eguid.livepush.conf.ConfUtil; 11 | import cc.eguid.livepush.dao.HandlerDao; 12 | import cc.eguid.livepush.dao.HandlerDaoImpl; 13 | import cc.eguid.livepush.handler.OutHandler; 14 | import cc.eguid.livepush.handler.PushHandler; 15 | import cc.eguid.livepush.handler.PushHandlerImpl; 16 | 17 | /** 18 | * 实现push管理器的push,delete,view服务 19 | * 20 | * @author eguid 21 | * @version 2016年6月24日 22 | * @see PushMangerImpl 23 | * @since jdk1.7 24 | */ 25 | 26 | public class PushManagerImpl implements PushManager { 27 | /** 28 | * 配置文件 29 | */ 30 | private ConfUtil confUtil = new ConfUtil(); 31 | 32 | public PushManagerImpl() { 33 | confUtil.isHave(); 34 | } 35 | 36 | /** 37 | * 引用push处理器 38 | */ 39 | private PushHandler pusher = new PushHandlerImpl(); 40 | 41 | /** 42 | * 管理处理器的主进程Process及两个输出线程的关系 43 | */ 44 | private HandlerDao hd = new HandlerDaoImpl(); 45 | 46 | public synchronized void setPusher(PushHandler pusher) { 47 | this.pusher = pusher; 48 | } 49 | 50 | public synchronized void setHd(HandlerDao hd) { 51 | this.hd = hd; 52 | } 53 | 54 | @Override 55 | public synchronized String push(Map parammap) { 56 | String appName = null; 57 | ConcurrentMap resultMap = null; 58 | try { 59 | // ffmpeg环境是否配置正确 60 | if (!confUtil.isHave()) { 61 | return null; 62 | } 63 | // 参数是否符合要求 64 | if (parammap == null || parammap.isEmpty() || !parammap.containsKey("appName")) { 65 | return null; 66 | } 67 | appName = (String) parammap.get("appName"); 68 | if (appName != null && "".equals(appName.trim())) { 69 | return null; 70 | } 71 | parammap.put("ffmpegPath", confUtil.getPath()); 72 | resultMap = pusher.push(parammap); 73 | // 处理器和输出线程对应关系 74 | hd.set(appName, resultMap); 75 | } catch (Exception e) { 76 | // 暂时先写这样,后期加日志 77 | System.err.println("重大错误:参数不符合要求或运行失败" + e.getMessage()); 78 | return null; 79 | } 80 | return appName; 81 | 82 | } 83 | 84 | @Override 85 | public synchronized boolean closePush(String appName) { 86 | if (hd.isHave(appName)) { 87 | ConcurrentMap map = hd.get(appName); 88 | // 关闭两个线程 89 | ((OutHandler) map.get("error")).destroy(); 90 | // ((OutHandler)map.get("info")).destroy(); 91 | // 暂时先这样写,后期加日志 92 | System.out.println("停止命令-----end commond"); 93 | // 关闭命令主进程 94 | ((Process) map.get("process")).destroy(); 95 | // 删除处理器与线程对应关系表 96 | hd.delete(appName); 97 | return true; 98 | } 99 | return false; 100 | } 101 | 102 | @Override 103 | public synchronized Set viewAppName() { 104 | return hd.getAllAppName(); 105 | } 106 | 107 | @Override 108 | public synchronized boolean isHave(String appName) { 109 | hd.isHave(appName); 110 | return false; 111 | 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/cc/eguid/livepush/Readme: -------------------------------------------------------------------------------- 1 | livePush0.2.1使用说明: 2 | (重要:使用前必须保证ffmpeg环境包在该项目的WEB-INF\classes\cc\eguid\livepush\ffmpeg\目录中) 3 | 1、对象创建 4 | PushManager pusher = new PushManagerImpl(); 5 | 6 | 2、参数说明及设置 7 | 2.1、参数说明 8 | name:应用名; 9 | input:接收地址; 10 | output:推送地址; 11 | codec:视频编码; 12 | fmt:视频格式; 13 | fps:视频帧率; 14 | rs:视频分辨率; 15 | twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码) 16 | 2.2、参数使用 17 | Map map = new HashMap(); 18 | map.put("appName", "testwanglaing123"); 19 | map.put("input","rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0"); 20 | map.put("output", "rtmp://192.168.30.21/live/"); 21 | map.put("codec","h264"); 22 | map.put("fmt", "flv"); 23 | map.put("fps", "25"); 24 | map.put("rs", "640x360"); 25 | map.put("twoPart","2"); 26 | 27 | 3、调用方法 28 | 3.1、发布方法 29 | id push(map) 30 | pusher.push(map); 31 | 32 | 3.2、关闭发布方法 33 | void closePush(appName) 34 | pusher.closePush(appName); 35 | 36 | 3.3、查看所有正在push的列表 37 | Set viewAppName() 38 | pusher.viewAppName(); 39 | 40 | 3.4、检测是否存在某个push 41 | boolean isHave(String appName) 42 | pusher.isHave(appName); -------------------------------------------------------------------------------- /src/cc/eguid/livepush/conf/ConfUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 文件名:ConfUtil.java 描述:读取配置文件属性 修改人:eguid 修改时间:2016年7月8日 修改内容: 3 | */ 4 | package cc.eguid.livepush.conf; 5 | 6 | import java.io.File; 7 | 8 | /** 9 | * 读取配置文件 10 | * 11 | * @author eguid 12 | * @version 2016年7月8日 13 | * @see ConfUtil 14 | * @since jdk1.7 15 | */ 16 | 17 | public class ConfUtil 18 | { 19 | private volatile static boolean isHave=false; 20 | private volatile static String ffmpegPath=null; 21 | public ConfUtil() 22 | { 23 | super(); 24 | initConfInfo(); 25 | } 26 | 27 | /** 28 | * 从配置文件中初始化参数 29 | */ 30 | private void initConfInfo() 31 | { 32 | 33 | String path = getClass().getResource("../").getPath() + "ffmpeg/ffmpeg.exe"; 34 | System.out.print("预加载FFMPEG配置:"+path); 35 | File ffmpeg =new File(path); 36 | ffmpegPath=ffmpeg.getPath(); 37 | if (isHave=ffmpeg.isFile()) 38 | { 39 | System.out.println("加载ffmpeg成功!"); 40 | } 41 | else 42 | { 43 | System.out.println("加载ffmpeg失败!"); 44 | } 45 | } 46 | 47 | /** 48 | *判断ffmpeg环境配置 49 | * @return true:配置成功;false:配置失败 50 | */ 51 | public boolean isHave() 52 | { 53 | return isHave; 54 | } 55 | /** 56 | * 获取ffmpeg环境调用地址 57 | * 添加方法功能描述 58 | * @return 59 | */ 60 | public String getPath() 61 | { 62 | return ffmpegPath; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/cc/eguid/livepush/dao/HandlerDao.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 文件名:HandlerDao.java 3 | * 描述:管理所有命令行处理器的缓存 4 | * 修改人:eguid 5 | * 修改时间:2016年6月27日 6 | * 修改内容: 7 | */ 8 | package cc.eguid.livepush.dao; 9 | 10 | import java.util.Set; 11 | import java.util.concurrent.ConcurrentMap; 12 | 13 | /** 14 | * 命令行执行处理器缓存,方便管理处理器的开启和关闭 15 | * @author eguid 16 | * @version 2016年6月27日 17 | * @see HandlerDao 18 | * @since jdk1.7 19 | */ 20 | 21 | public interface HandlerDao 22 | { 23 | /** 24 | * 获取某个处理器 25 | * @param pushId 26 | * @return 27 | */ 28 | public ConcurrentMap get(String pushId); 29 | /** 30 | * 存放一个处理器 31 | * @param handlerMap 32 | */ 33 | public void set(String key, ConcurrentMap resultMap); 34 | /** 35 | * 获取全部处理器 36 | * @return 37 | */ 38 | public ConcurrentMap> getAll(); 39 | /** 40 | * 获取全部处理器名称 41 | * @return 42 | */ 43 | public Set getAllAppName(); 44 | /** 45 | * 删除某个处理器 46 | * @param pushId 47 | */ 48 | public void delete(String appName); 49 | /** 50 | * 是否存在key 51 | */ 52 | public boolean isHave(String appName); 53 | } 54 | -------------------------------------------------------------------------------- /src/cc/eguid/livepush/dao/HandlerDaoImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 文件名:HandlerDaoImpl.java 描述:命令行执行处理器缓存的简单实现 修改人:eguid 修改时间:2016年6月27日 修改内容: 3 | */ 4 | package cc.eguid.livepush.dao; 5 | 6 | import java.util.Set; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | import java.util.concurrent.ConcurrentMap; 9 | 10 | 11 | /** 12 | * 处理器的缓存简单实现 13 | * @author eguid 14 | * @version 2016年6月27日 15 | * @see HandlerDaoImpl 16 | * @since jdk1.7 17 | */ 18 | 19 | public class HandlerDaoImpl implements HandlerDao 20 | { 21 | /** 22 | * 存放process 23 | */ 24 | private static ConcurrentMap> handlerMap = new ConcurrentHashMap>(20); 25 | 26 | @Override 27 | public ConcurrentMap get(String pushId) 28 | { 29 | if(handlerMap.containsKey(pushId)) 30 | { 31 | return handlerMap.get(pushId); 32 | } 33 | return null; 34 | } 35 | 36 | @Override 37 | public ConcurrentMap> getAll() 38 | { 39 | return handlerMap; 40 | } 41 | 42 | @Override 43 | public void delete(String pushId) 44 | { 45 | if (pushId != null) 46 | { 47 | handlerMap.remove(pushId); 48 | } 49 | } 50 | 51 | @Override 52 | public void set(String key, ConcurrentMap map) 53 | { 54 | if (key != null) 55 | { 56 | handlerMap.put(key, map); 57 | } 58 | } 59 | 60 | @Override 61 | public boolean isHave(String pushId) 62 | { 63 | return handlerMap.containsKey(pushId); 64 | } 65 | 66 | @Override 67 | public Set getAllAppName() 68 | { 69 | return handlerMap.keySet(); 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/cc/eguid/livepush/entity/LivePushEntity.java: -------------------------------------------------------------------------------- 1 | package cc.eguid.livepush.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | public class LivePushEntity implements Serializable { 6 | private static final long serialVersionUID = -1580871796857185739L; 7 | 8 | public LivePushEntity() { 9 | super(); 10 | } 11 | 12 | /** 13 | * 示例: appName="test123" 14 | * input="rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0" 15 | * output="rtmp://192.168.30.21/live/" codec="h264" fmt="flv" fps="25" 16 | * rs="640x360" twoPart="2" twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码) 17 | */ 18 | 19 | public LivePushEntity(String appName, String input, String output, String codec, String fmt, String fps, String rs, 20 | String twoPart) { 21 | super(); 22 | this.appName = appName; 23 | this.input = input; 24 | this.output = output; 25 | this.fmt = fmt; 26 | this.fps = fps; 27 | this.rs = rs; 28 | this.codec = codec; 29 | this.twoPart = twoPart; 30 | } 31 | 32 | /** 33 | * 应用名 34 | */ 35 | private String appName; 36 | 37 | /** 38 | * 视频源地址,可以是实时流地址也可以是文件路径 39 | */ 40 | private String input; 41 | 42 | /** 43 | * 实时流输出地址,这个默认是固定的rtmp服务器发布地址 44 | */ 45 | private String output; 46 | 47 | /** 48 | * 视频格式,默认flv 49 | */ 50 | private String fmt; 51 | 52 | /** 53 | * 帧率,最好是25-60 54 | */ 55 | private String fps; 56 | 57 | /** 58 | * 分辨率,例如:640x360 59 | */ 60 | private String rs; 61 | 62 | /** 63 | * 视频编码 64 | */ 65 | private String codec; 66 | /** 67 | * twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码) 68 | */ 69 | private String twoPart; 70 | 71 | /** 72 | * @return the appName 73 | */ 74 | public String getAppName() { 75 | return appName; 76 | } 77 | 78 | /** 79 | * @param appName 80 | * the appName to set 81 | */ 82 | public void setAppName(String appName) { 83 | this.appName = appName; 84 | } 85 | 86 | /** 87 | * @return the input 88 | */ 89 | public String getInput() { 90 | return input; 91 | } 92 | 93 | /** 94 | * @param input 95 | * the input to set 96 | */ 97 | public void setInput(String input) { 98 | this.input = input; 99 | } 100 | 101 | /** 102 | * @return the output 103 | */ 104 | public String getOutput() { 105 | return output; 106 | } 107 | 108 | /** 109 | * @param output 110 | * the output to set 111 | */ 112 | public void setOutput(String output) { 113 | this.output = output; 114 | } 115 | 116 | /** 117 | * @return the fmt 118 | */ 119 | public String getFmt() { 120 | return fmt; 121 | } 122 | 123 | /** 124 | * @param fmt 125 | * the fmt to set 126 | */ 127 | public void setFmt(String fmt) { 128 | this.fmt = fmt; 129 | } 130 | 131 | /** 132 | * @return the fps 133 | */ 134 | public String getFps() { 135 | return fps; 136 | } 137 | 138 | /** 139 | * @param fps 140 | * the fps to set 141 | */ 142 | public void setFps(String fps) { 143 | this.fps = fps; 144 | } 145 | 146 | /** 147 | * @return the rs 148 | */ 149 | public String getRs() { 150 | return rs; 151 | } 152 | 153 | /** 154 | * @param rs 155 | * the rs to set 156 | */ 157 | public void setRs(String rs) { 158 | this.rs = rs; 159 | } 160 | 161 | /** 162 | * @return the codec 163 | */ 164 | public String getCodec() { 165 | return codec; 166 | } 167 | 168 | /** 169 | * @param codec 170 | */ 171 | public void setCodec(String codec) { 172 | this.codec = codec; 173 | } 174 | 175 | public String getTwoPart() { 176 | return twoPart; 177 | } 178 | 179 | public void setTwoPart(String twoPart) { 180 | this.twoPart = twoPart; 181 | } 182 | 183 | } 184 | -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/avcodec-57.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/avcodec-57.dll -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/avdevice-57.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/avdevice-57.dll -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/avfilter-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/avfilter-6.dll -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/avformat-57.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/avformat-57.dll -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/avutil-55.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/avutil-55.dll -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/ffmpeg.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/ffmpeg.exe -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/ffplay.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/ffplay.exe -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/ffprobe.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/ffprobe.exe -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/postproc-54.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/postproc-54.dll -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/swresample-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/swresample-2.dll -------------------------------------------------------------------------------- /src/cc/eguid/livepush/ffmpeg/swscale-4.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eguid/livePush/19cb112637e0637f553fd074cd67e6786cacdf01/src/cc/eguid/livepush/ffmpeg/swscale-4.dll -------------------------------------------------------------------------------- /src/cc/eguid/livepush/handler/OutHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 文件名:OutHandler.java 描述:输出命令行主进程消息 修改人:eguid 修改时间:2016年6月27日 修改内容: 3 | */ 4 | package cc.eguid.livepush.handler; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.InputStreamReader; 10 | 11 | /** 12 | * 用于输出命令行主进程的消息线程(必须开启,否则命令行主进程无法正常执行) 重要:该类重写了destroy方法,用于安全的关闭该线程 13 | * 14 | * @author eguid 15 | * @version 2016年6月27日 16 | * @see OutHandler 17 | * @since jdk1.7 18 | */ 19 | 20 | public class OutHandler extends Thread { 21 | /** 22 | * 控制状态 23 | */ 24 | private volatile boolean desstatus = true; 25 | 26 | /** 27 | * 读取输出流 28 | */ 29 | private BufferedReader br = null; 30 | 31 | /** 32 | * 输出类型 33 | */ 34 | private String type = null; 35 | 36 | public OutHandler(InputStream is, String type) { 37 | br = new BufferedReader(new InputStreamReader(is)); 38 | this.type = type; 39 | } 40 | 41 | /** 42 | * 重写线程销毁方法,安全的关闭线程 43 | */ 44 | @Override 45 | public void destroy() { 46 | setDesStatus(false); 47 | } 48 | 49 | public void setDesStatus(boolean desStatus) { 50 | this.desstatus = desStatus; 51 | } 52 | 53 | /** 54 | * 执行输出线程 55 | */ 56 | @Override 57 | public void run() { 58 | String msg = null; 59 | int index = 0; 60 | int errorIndex = 0; 61 | int status = 10; 62 | try { 63 | System.out.println(type + "开始推流!"); 64 | while (desstatus && (msg = br.readLine()) != null) { 65 | if (msg.indexOf("[rtsp") != -1) { 66 | System.out.println("接收" + status + "个数据包" + msg); 67 | System.out.println(type + ",网络异常丢包,丢包次数:" + errorIndex++ + ",消息体:" + msg); 68 | status = 10; 69 | index = 0; 70 | } 71 | 72 | if (index % status == 0) { 73 | System.out.println("接收" + status + "个数据包" + msg); 74 | status *= 2; 75 | } 76 | index++; 77 | } 78 | } catch (IOException e) { 79 | System.out.println("发生内部异常错误,自动关闭[" + this.getId() + "]线程"); 80 | destroy(); 81 | } finally { 82 | if (this.isAlive()) { 83 | destroy(); 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/cc/eguid/livepush/handler/PushHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 文件名:PushHandler.java 3 | * 描述:push操作处理器接口 4 | * 修改人:eguid 5 | * 修改时间:2016年6月24日 6 | * 修改内容: 7 | */ 8 | package cc.eguid.livepush.handler; 9 | 10 | import java.io.IOException; 11 | import java.util.Map; 12 | import java.util.concurrent.ConcurrentMap; 13 | 14 | /** 15 | * 用于提供处理push操作的服务接口 16 | * @author eguid 17 | * @version 2016年6月24日 18 | * @see PushHandler 19 | * @since jdk1.7 20 | */ 21 | 22 | public interface PushHandler 23 | { 24 | /** 25 | * 处理push操作(包含一个主进程和两个输出线程) 26 | * @param parammap 27 | * 格式: 28 | * name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率;disableAudio:是否开启音频 29 | * @return map(进程,消息(info,error)) 30 | * @throws IOException 31 | * 32 | */ 33 | public ConcurrentMap push(Map parammap)throws Exception; 34 | } 35 | -------------------------------------------------------------------------------- /src/cc/eguid/livepush/handler/PushHandlerImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 文件名:PushHandlerImpl.java 描述: 修改人:eguid 修改时间:2016年6月24日 修改内容: 3 | */ 4 | package cc.eguid.livepush.handler; 5 | 6 | import java.util.Map; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | import java.util.concurrent.ConcurrentMap; 9 | 10 | /** 11 | * 提供解析参数生成ffmpeg命令并处理push操作 12 | * 13 | * @author eguid 14 | * @version 2016年6月24日 15 | * @see PushHandlerImpl 16 | * @since jdk1.7 17 | */ 18 | 19 | public class PushHandlerImpl implements PushHandler { 20 | 21 | @Override 22 | public ConcurrentMap push(Map paramMap) throws Exception { 23 | ConcurrentMap resultMap = null; 24 | Process proc =null; 25 | OutHandler errorGobbler=null; 26 | try{ 27 | // 从map里面取数据,组装成命令 28 | String comm = getComm4Map(paramMap); 29 | if(comm==null) 30 | { 31 | throw new Exception(); 32 | } 33 | // 执行命令行 34 | System.out.println("执行命令:" + comm); 35 | proc = Runtime.getRuntime().exec(comm); 36 | 37 | errorGobbler = new OutHandler(proc.getErrorStream(), (String) paramMap.get("appName")); 38 | errorGobbler.start(); 39 | 40 | // 返回参数 41 | resultMap = new ConcurrentHashMap(); 42 | // resultMap.put("info", outputGobbler); 43 | resultMap.put("error", errorGobbler); 44 | resultMap.put("process", proc); 45 | }catch(Exception e){ 46 | if(proc!=null){ 47 | proc.destroy(); 48 | } 49 | if(errorGobbler!=null){ 50 | errorGobbler.destroy(); 51 | } 52 | throw e; 53 | } 54 | return resultMap; 55 | } 56 | 57 | /* 58 | * "ffmpeg -i "+ 59 | * "rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0 " 60 | * + " -f flv -r 25 -s 640x360 -an" + " rtmp://192.168.30.21/live/test" 61 | * 推送流格式: 62 | * name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率 63 | * 是否开启音频 64 | */ 65 | /** 66 | * 通过解析参数生成可执行的命令行字符串; 67 | * name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率 68 | * "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" 69 | * @param paramMap 70 | * @throws Exception 71 | * @return 命令行字符串 72 | */ 73 | protected String getComm4Map(Map paramMap) throws Exception{ 74 | try{ 75 | if (paramMap.containsKey("ffmpegPath")) { 76 | String ffmpegPath = (String) paramMap.get("ffmpegPath"); 77 | // -i:输入流地址或者文件绝对地址 78 | StringBuilder comm = new StringBuilder(ffmpegPath + " -i "); 79 | // 是否有必输项:输入地址,输出地址,应用名,twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码) 80 | if (paramMap.containsKey("input") && paramMap.containsKey("output") && paramMap.containsKey("appName")&& paramMap.containsKey("twoPart")) { 81 | String input = (String) paramMap.get("input"); 82 | String output = (String) paramMap.get("output"); 83 | String appName = (String) paramMap.get("appName"); 84 | String twoPart = (String) paramMap.get("twoPart"); 85 | String codec=(String) paramMap.get("codec"); 86 | //默认h264解码 87 | codec=(codec==null?"h264":(String) paramMap.get("codec")); 88 | // 输入地址 89 | comm.append(input); 90 | // 当twoPart为0时,只推一个元码流 91 | if ("0".equals(twoPart)) { 92 | comm.append(" -vcodec "+codec+" -f flv -an "+output + appName); 93 | }else{ 94 | // -f :转换格式,默认flv 95 | if (paramMap.containsKey("fmt")) { 96 | String fmt = (String) paramMap.get("fmt"); 97 | comm.append(" -f " + fmt); 98 | } 99 | // -r :帧率,默认25;-g :帧间隔 100 | if (paramMap.containsKey("fps")) { 101 | String fps = (String) paramMap.get("fps"); 102 | comm.append(" -r " + fps); 103 | comm.append(" -g " + fps); 104 | } 105 | // -s 分辨率 默认是原分辨率 106 | if (paramMap.containsKey("rs")) { 107 | String rs = (String) paramMap.get("rs"); 108 | comm.append(" -s " + rs); 109 | } 110 | // 输出地址+发布的应用名 111 | comm.append(" -an "+output + appName); 112 | // 当twoPart为2时推两个流,一个自定义流,一个元码流 113 | if ("2".equals(twoPart)) { 114 | // 一个视频源,可以有多个输出,第二个输出为拷贝源视频输出,不改变视频的各项参数并且命名为应用名+HD 115 | comm.append(" -vcodec copy -f flv -an ").append(output +appName+ "HD"); 116 | } 117 | } 118 | return comm.toString(); 119 | } 120 | } 121 | }catch(Exception e){ 122 | throw e; 123 | } 124 | return null; 125 | } 126 | } 127 | --------------------------------------------------------------------------------