ffch/src/main/java/com/github/bluesbruce/spring/service/RtmpLiveService.java

327 lines
13 KiB
Java

package com.github.bluesbruce.spring.service;
import com.github.bluesbruce.ffch.CommandManager;
import com.github.bluesbruce.ffch.CommandManagerImpl;
import com.github.bluesbruce.ffch.commandbuidler.CommandBuidlerFactory;
import com.github.bluesbruce.ffch.data.CommandTasker;
import com.alibaba.fastjson.JSONObject;
import com.github.bluesbruce.spring.config.CmdParam;
import com.github.bluesbruce.spring.mqttService.HttpURLConnectionUtil;
import com.github.bluesbruce.spring.mqttService.send.MqttProviderConfig;
import lombok.extern.slf4j.Slf4j;
import org.h2.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.List;
import static com.github.bluesbruce.ffch.util.PropertiesUtil.load;
@Service
@Slf4j
public class RtmpLiveService {
/**
* 加载配置文件的推拉流地址
*/
public static final CmdParam cmdParam = load("/loadCmd.properties", CmdParam.class);
@Autowired
private MqttProviderConfig mqttProviderConfig;
public static final CommandManager manager = new CommandManagerImpl();
/**
* h获取通道并推送
*/
public void pushServer(String code) throws InterruptedException {
//CommandManager manager = new CommandManagerImpl();
String reTopic = cmdParam.getMqttTopic().replace("live", "result");
JSONObject jsonObject = new JSONObject();
Collection<CommandTasker> infoList = manager.queryAll();
log.info(infoList.toString());
if (infoList.size() > 0) {
//manager.stopAll();
//manager.destory();
//Thread.sleep(3000);
/*jsonObject.put("code", -1);
jsonObject.put("msg", "推流服务已启动,请勿重复启动"); //推流失败
mqttProviderConfig.publish(2,false,reTopic,jsonObject.toJSONString());*/
log.info("任务运行中");
return;
}
String pushUrl = "";
if (cmdParam.getType() == 2) {
log.info("获取流媒体通道");
//TODO 获取通道服务推拉流地址
JSONObject object = getChenl();
if (!ObjectUtils.isEmpty(object)) {
code = object.get("code").toString();
object.put("code", 0);
object.put("msg", "获取通道成功");
mqttProviderConfig.publish(2, false, reTopic, object.toJSONString());
} else {
log.info("获取通道失败");
object.put("code", -1);
object.put("msg", "获取通道失败");
mqttProviderConfig.publish(2, false, reTopic, object.toJSONString());
return;
}
runRtmp(pushUrl, cmdParam.getPlayUrl(), code);
//TODO end
} else if (cmdParam.getType() == 1) {
log.info("使用固定流媒体通道");
pushUrl = cmdParam.getPushUrl();
runRtmp(pushUrl, cmdParam.getPlayUrl(), code);
} else if (cmdParam.getType() == 3) {
runRtmp2to2(cmdParam.getPlayUrl());
} else if (cmdParam.getType() == 4) {
runRtmp1to2(cmdParam.getPlayUrl());
}
}
private void runRtmp2to2(String playUrl) throws InterruptedException {
try {
String reTopic = cmdParam.getMqttTopic().replace("live", "result");
String taskId = manager.start("test1", CommandBuidlerFactory.createBuidler()
.add("ffmpeg").add("-i", playUrl)
.add("-rtsp_transport", "tcp")
.add("-vcodec", "copy")
.add("-acodec", "copy")
.add("-f", "flv")
.add("-b:v", "2M")
.add("-maxrate", "2M")
.add("-bufsize", "1M")
.add("-y").add(cmdParam.getPushUrl()));
Thread.sleep(3000);
String taskId2 = manager.start("test2", CommandBuidlerFactory.createBuidler()
.add("ffmpeg").add("-i", playUrl)
.add("-rtsp_transport", "tcp")
.add("-vcodec", "copy")
.add("-acodec", "copy")
.add("-f", "flv")
.add("-b:v", "2M")
.add("-maxrate", "2M")
.add("-bufsize", "1M")
.add("-y").add(cmdParam.getPushUrl2()));
JSONObject jsonObject = new JSONObject();
if (StringUtils.isNullOrEmpty(taskId) && StringUtils.isNullOrEmpty(taskId2)) {
jsonObject.put("code", -1);
jsonObject.put("msg", "推流服务失败"); //推流失败
mqttProviderConfig.publish(2, false, reTopic, jsonObject.toJSONString());
// 停止全部任务
manager.stopAll();
return;
} else {
jsonObject.put("code", 0);
jsonObject.put("msg", "推流服务启动成功");
mqttProviderConfig.publish(2, false, reTopic, jsonObject.toJSONString());
}
Thread.sleep(cmdParam.getTime());
log.info(manager.queryAll().toString());
// 停止全部任务
manager.stopAll();
manager.destory();
} catch (Exception e) {
e.printStackTrace();
}
}
private void runRtmp1to2(String playUrl) {
try {
//单进程 多路
String reTopic = cmdParam.getMqttTopic().replace("live", "result");
String taskId = manager.start("test4", CommandBuidlerFactory.createBuidler()
.add("ffmpeg").add("-i", playUrl)
.add("-rtsp_transport", "tcp")
.add("-vcodec", "copy")
.add("-acodec", "copy")
.add("-b:v", "2M")
.add("-maxrate", "2M")
.add("-bufsize", "1M")
//多路推流测试
.add("-map", "0")
.add("-f").add(cmdParam.getPushUrlMap()));
JSONObject jsonObject = new JSONObject();
if (StringUtils.isNullOrEmpty(taskId)) {
jsonObject.put("code", -1);
jsonObject.put("msg", "推流服务失败"); //推流失败
mqttProviderConfig.publish(2, false, reTopic, jsonObject.toJSONString());
// 停止全部任务
manager.stopAll();
return;
} else {
jsonObject.put("code", 0);
jsonObject.put("msg", "推流服务启动成功");
mqttProviderConfig.publish(2, false, reTopic, jsonObject.toJSONString());
}
Thread.sleep(cmdParam.getTime());
log.info(manager.queryAll().toString());
// 停止全部任务
manager.stopAll();
manager.destory();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取阿里云通道
*
* @return
*/
private JSONObject getChenl() {
String result = HttpURLConnectionUtil.doGet("https://streaming.t-aaron.com/livechannel/getLiveChannelList");
if (!StringUtils.isNullOrEmpty(result)) {
try {
JSONObject object = JSONObject.parseObject(result);
List<JSONObject> objectList = (List<JSONObject>) object.get("data");
if (objectList.size() > 0) {
log.info("获取到通道列表{}", objectList);
for (int i = 0; i < objectList.size(); i++) {
JSONObject chenl = objectList.get(i);
//设置通道占用
JSONObject param = new JSONObject();
param.put("code", chenl.get("code").toString());
String resultOn = HttpURLConnectionUtil.doPut("https://streaming.t-aaron.com/livechannel/useLiveChannel", param.toJSONString());
if (!StringUtils.isNullOrEmpty(resultOn)) {
JSONObject objectResult = JSONObject.parseObject(resultOn);
if (objectResult.get("code").toString().equals("0")) {
log.info("占用通道{}", objectList.get(i));
return objectList.get(i);
}
}
}
}
} catch (Exception e) {
log.error("", e);
}
} else {
return null;
}
return null;
}
/**
* 根据推拉流地址推动
*
* @param pushUrl
* @param playUrl
*/
public void runRtmp(String pushUrl, String playUrl, String code) {
try {
log.info("获取播流地址:{}");
//CommandManager manager = new CommandManagerImpl();
String taskId = manager.start(code, CommandBuidlerFactory.createBuidler()
.add("ffmpeg").add("-i", playUrl)
.add("-rtsp_transport", "tcp")
.add("-vcodec", "copy")
.add("-acodec", "copy")
.add("-f", "flv")
.add("-b:v", "2M")
.add("-maxrate", "2M")
.add("-bufsize", "1M")
.add("-v", "trace ")
.add("-y").add(pushUrl));
cmdParam.getMqttTopic();
String reTopic = cmdParam.getMqttTopic().replace("live", "result");
log.info(manager.queryAll().toString());
JSONObject jsonObject = new JSONObject();
if (StringUtils.isNullOrEmpty(taskId)) {
jsonObject.put("code", -1);
jsonObject.put("msg", "推流服务失败"); //推流失败
mqttProviderConfig.publish(2, false, reTopic, jsonObject.toJSONString());
// 停止全部任务
manager.stopAll();
return;
} else {
jsonObject.put("code", 0);
jsonObject.put("msg", "推流服务启动成功");
mqttProviderConfig.publish(2, false, reTopic, jsonObject.toJSONString());
}
Thread.sleep(cmdParam.getTime());
log.info(manager.queryAll().toString());
// 停止全部任务
manager.stopAll();
manager.destory();
} catch (Exception e) {
log.error("", e);
}
//ds.close();
}
public void stopRtmp() {
try {
log.info("停止推流");
//CommandManager manager = new CommandManagerImpl();
// 停止全部任务
int index = manager.stopAll();
manager.destory();
JSONObject jsonObject = new JSONObject();
String reTopic = cmdParam.getMqttTopic().replace("live", "result");
if (index == 0) {
jsonObject.put("code", -1);
jsonObject.put("msg", "推流服务关闭失败"); //推流失败
mqttProviderConfig.publish(2, false, reTopic, jsonObject.toJSONString());
// 停止全部任务
manager.stopAll();
return;
} else if (index > 0) {
jsonObject.put("code", 0);
jsonObject.put("msg", "推流服务关闭成功");
returnChenl();
mqttProviderConfig.publish(2, false, reTopic, jsonObject.toJSONString());
}
} catch (Exception e) {
log.error("", e);
}
//ds.close();
}
/**
* 释放阿里云通道
*
* @return
*/
private JSONObject returnChenl() {
try {
String result = HttpURLConnectionUtil.doGet("https://streaming.t-aaron.com/livechannel/getLiveChannelList");
if (!StringUtils.isNullOrEmpty(result)) {
JSONObject object = JSONObject.parseObject(result);
List<JSONObject> objectList = (List<JSONObject>) object.get("data");
if (objectList.size() > 0) {
log.info("获取到通道列表{}", objectList);
for (int i = 0; i < objectList.size(); i++) {
JSONObject chenl = objectList.get(i);
//设置通道占用
JSONObject param = new JSONObject();
param.put("code", chenl.get("code").toString());
String resultOn = HttpURLConnectionUtil.doPut("https://streaming.t-aaron.com/livechannel/useLiveChannel", param.toJSONString());
if (!StringUtils.isNullOrEmpty(resultOn)) {
JSONObject objectResult = JSONObject.parseObject(resultOn);
if (objectResult.get("code").toString().equals("0")) {
log.info("占用通道{}", objectList.get(i));
return objectList.get(i);
}
}
}
}
} else {
return null;
}
return null;
} catch (Exception e) {
log.error("", e);
}
return null;
}
}