├── .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 |
--------------------------------------------------------------------------------