/*
|
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
*
|
* Redistribution and use in source and binary forms, with or without
|
* modification, are permitted provided that the following conditions are met:
|
*
|
* Redistributions of source code must retain the above copyright notice,
|
* this list of conditions and the following disclaimer.
|
* Redistributions in binary form must reproduce the above copyright
|
* notice, this list of conditions and the following disclaimer in the
|
* documentation and/or other materials provided with the distribution.
|
* Neither the name of the dreamlu.net developer nor the names of its
|
* contributors may be used to endorse or promote products derived from
|
* this software without specific prior written permission.
|
* Author: Chill 庄骞 (smallchill@163.com)
|
*/
|
package org.springblade.jfpt.rvideo.controller;
|
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiParam;
|
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
import lombok.AllArgsConstructor;
|
import javax.validation.Valid;
|
import net.logstash.logback.encoder.org.apache.commons.lang3.StringEscapeUtils;
|
import org.springblade.core.mp.support.Condition;
|
import org.springblade.core.mp.support.Query;
|
import org.springblade.core.tool.api.R;
|
import org.springblade.core.tool.utils.DateUtil;
|
import org.springblade.core.tool.utils.Func;
|
import org.springblade.jfpt.alarm.service.IAlarmService;
|
import org.springblade.jfpt.xlfeedback.service.IXlfeedbackService;
|
import org.springframework.web.bind.annotation.*;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import org.springblade.jfpt.rvideo.entity.Rvideo;
|
import org.springblade.jfpt.rvideo.vo.RvideoVO;
|
import org.springblade.jfpt.rvideo.service.IRvideoService;
|
import org.springblade.core.boot.ctrl.BladeController;
|
import java.io.File;
|
|
import org.bytedeco.javacpp.avcodec;
|
import org.bytedeco.javacv.*;
|
import java.io.IOException;
|
import java.util.Date;
|
|
|
/**
|
* 控制器
|
*
|
* @author BladeX
|
* @since 2021-03-24
|
*/
|
@RestController
|
@AllArgsConstructor
|
@RequestMapping("/rvideo")
|
@Api(value = "", tags = "接口")
|
public class RvideoController extends BladeController {
|
|
private final IRvideoService rvideoService;
|
private final IAlarmService alarmService;
|
private final IXlfeedbackService xlfeedbackService;
|
private static String PRE_URL = "D:\\software\\minio\\data\\jfpt\\void\\";
|
private static String PRF_MINIO_URL = "minio/jfpt/void/";
|
private static Thread thread;
|
private static String UUIDs;
|
private static String uids;
|
private static int count=0;
|
private static String xcbj = "cs";
|
|
//录制视频相关
|
private static String streamURL;// 流地址(测试可以用obs推流)
|
private static String filePath;// 文件路径
|
private static Long timesSec = 100L;// 停止录制时长 0为不限制时长
|
private static String fileFormat = "mp4";//录制的文件格式
|
private static boolean isAudio = false;//是否录制声音
|
private static boolean stop = false;
|
|
/**
|
* 详情
|
*/
|
@GetMapping("/detail")
|
@ApiOperationSupport(order = 1)
|
@ApiOperation(value = "详情", notes = "传入rvideo")
|
public R<Rvideo> detail(Rvideo rvideo) {
|
Rvideo detail = rvideoService.getOne(Condition.getQueryWrapper(rvideo));
|
return R.data(detail);
|
}
|
|
/**
|
* 分页
|
*/
|
@GetMapping("/list")
|
@ApiOperationSupport(order = 2)
|
@ApiOperation(value = "分页", notes = "传入rvideo")
|
public R<IPage<Rvideo>> list(Rvideo rvideo, Query query) {
|
IPage<Rvideo> pages = rvideoService.page(Condition.getPage(query), Condition.getQueryWrapper(rvideo));
|
return R.data(pages);
|
}
|
|
/**
|
* 自定义分页
|
*/
|
@GetMapping("/page")
|
@ApiOperationSupport(order = 3)
|
@ApiOperation(value = "分页", notes = "传入rvideo")
|
public R<IPage<RvideoVO>> page(RvideoVO rvideo, Query query) {
|
IPage<RvideoVO> pages = rvideoService.selectRvideoPage(Condition.getPage(query), rvideo);
|
return R.data(pages);
|
}
|
|
/**
|
* 新增
|
*/
|
@PostMapping("/save")
|
@ApiOperationSupport(order = 4)
|
@ApiOperation(value = "新增", notes = "传入rvideo")
|
public R save(@Valid @RequestBody Rvideo rvideo) {
|
return R.status(rvideoService.save(rvideo));
|
}
|
|
/**
|
* 修改
|
*/
|
@PostMapping("/update")
|
@ApiOperationSupport(order = 5)
|
@ApiOperation(value = "修改", notes = "传入rvideo")
|
public R update(@Valid @RequestBody Rvideo rvideo) {
|
return R.status(rvideoService.updateById(rvideo));
|
}
|
|
/**
|
* 新增或修改
|
*/
|
@PostMapping("/submit")
|
@ApiOperationSupport(order = 6)
|
@ApiOperation(value = "新增或修改", notes = "传入rvideo")
|
public R submit(@Valid @RequestBody Rvideo rvideo) {
|
return R.status(rvideoService.saveOrUpdate(rvideo));
|
}
|
|
|
/**
|
* 删除
|
*/
|
|
@PostMapping("/remove")
|
@ApiOperationSupport(order = 8)
|
@ApiOperation(value = "删除", notes = "传入ids")
|
public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
|
return R.status(rvideoService.removeByIds(Func.toLongList(ids)));
|
}
|
|
// /**
|
// * @param sourcePath 源路径
|
// * @param jid 警情id
|
// * @throws Exception
|
// */
|
// @PostMapping("/rVoid")
|
// public String rVoid(String sourcePath,String jid) throws Exception {
|
// String webroot = "D:\\LXVideoServer\\3rd\\ffmpeg\\bin";
|
// String UUID = DateUtil.time();
|
// //目标路径
|
// String targetPath = PRE_URL + UUID + ".mp4";
|
// //返回前端路径
|
// String vaddress = null;
|
// Runtime run = null;
|
//
|
// try {
|
//
|
// run = Runtime.getRuntime();
|
//
|
// long start = System.currentTimeMillis();
|
//
|
// System.out.println(new File(webroot).getAbsolutePath());
|
// //通过视频url录制30s视频保存,格式为MP4
|
// String newJson = StringEscapeUtils.unescapeHtml4(sourcePath);
|
// Process p = run.exec(new File(webroot).getAbsolutePath() + "/ffmpeg -i " +newJson+ " -y -t 00:00:30 -codec copy -f mp4 " + targetPath);
|
//
|
// //释放进程
|
//
|
// p.getOutputStream().close();
|
//
|
// p.getInputStream().close();
|
//
|
// p.getErrorStream().close();
|
//
|
// p.waitFor();
|
//
|
// long end = System.currentTimeMillis();
|
//
|
// System.out.println(sourcePath + " convert success, costs:" + (end - start) + "ms");
|
//
|
// } catch (Exception e) {
|
//
|
// e.printStackTrace();
|
//
|
// } finally {
|
// //run调用lame解码器最后释放内存
|
// run.freeMemory();
|
// //返回路径
|
// vaddress = "https://web.byisf.com/" + PRF_MINIO_URL + UUID + ".mp4";
|
// //把路径通过警情id添加到警情信息
|
// alarmService.updateVaddress(vaddress,jid);
|
// }
|
// return vaddress;
|
// }
|
|
|
/**
|
* Javacv录制视频
|
*/
|
@PostMapping("/rVoids")
|
public void rVoids(String url,String uid,String jid) {
|
|
/*String UUID = DateUtil.time();
|
UUIDs=UUID;
|
uids=uid;
|
RecordVideoThread recordVideoThread = new RecordVideoThread();
|
recordVideoThread.filePath = "D:\\video\\"+UUID + ".mp4";
|
recordVideoThread.timesSec = 0L;
|
String newJson = StringEscapeUtils.unescapeHtml4(url);
|
recordVideoThread.streamURL =newJson;// 最好设置结束时长 如直接停止程序会造成输出文件的损坏无法正常播放
|
recordVideoThread.isAudio = true;
|
thread = new Thread(recordVideoThread);
|
thread.start();*/
|
|
String UUID = DateUtil.time();
|
UUIDs=UUID;
|
uids=uid;
|
//filePath = "D:\\video\\"+UUID + ".mp4";
|
filePath = "D:\\software\\minio\\data\\jfpt\\void\\"+UUID + ".mp4";
|
timesSec = 0L;
|
String newJson = StringEscapeUtils.unescapeHtml4(url);
|
streamURL =newJson;// 最好设置结束时长 如直接停止程序会造成输出文件的损坏无法正常播放
|
isAudio = true;
|
xcbj = "ce";
|
Thread threads = new Thread(new Runnable() {
|
@Override
|
public void run() {
|
//System.out.println("开始1111111");
|
|
// 获取视频源
|
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(streamURL);
|
FFmpegFrameRecorder recorder = null;
|
try {
|
grabber.start();
|
Frame frame = grabber.grabFrame();
|
createFile();
|
//"rtmp://192.168.1.225:1935/live/home"
|
// 流媒体输出地址,分辨率(长,高),是否录制音频(0:不录制/1:录制)
|
recorder = new FFmpegFrameRecorder(filePath, 1280, 720, isAudio ? 1 : 0);
|
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);// 直播流格式
|
recorder.setFormat(fileFormat);// 录制的视频格式
|
recorder.setFrameRate(10);// 帧数
|
//百度翻译的比特率,默认400000,但是我400000贼模糊,调成800000比较合适
|
recorder.setVideoBitrate(800000);
|
recorder.start();
|
System.out.println("推流开始");
|
|
//记录当前时间
|
long dqdate = new Date().getTime();
|
|
while (!jid.equals(xcbj)) {
|
//记录现在时间
|
long xzdate = new Date().getTime();
|
if (xzdate > (dqdate + 300000)){
|
break;
|
}
|
|
if (frame != null){
|
|
System.out.println("开始");
|
recorder.record(frame);//录制
|
frame = grabber.grabFrame();//获取下一帧
|
System.out.println("结束");
|
|
}
|
}
|
|
if (jid.equals(xcbj)){
|
recorder.record(frame);
|
}
|
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
//停止录制
|
if (null != grabber) {
|
try {
|
grabber.stop();
|
} catch (FrameGrabber.Exception e) {
|
e.printStackTrace();
|
}
|
}
|
if (recorder != null) {
|
try {
|
recorder.stop();
|
} catch (FrameRecorder.Exception e) {
|
e.printStackTrace();
|
}
|
}
|
System.out.println("录制完成,录制时长:" + timesSec + "秒");
|
|
String vaddress = null;
|
//返回路径
|
vaddress = "https://web.byisf.com/" + PRF_MINIO_URL + UUID + ".mp4";
|
//把路径通过警情id添加到警情信息
|
alarmService.updateVaddress(vaddress, uids, jid);
|
}
|
|
}
|
});
|
threads.start();
|
|
}
|
|
private void createFile() {
|
File outFile = new File(filePath);
|
if (filePath.isEmpty() || !outFile.exists() || outFile.isFile()) {
|
try {
|
outFile.createNewFile();
|
} catch (IOException e) {
|
// TODO Auto-generated catch block
|
e.printStackTrace();
|
}
|
}
|
|
}
|
|
@PostMapping("/stop")
|
public String stop(String jid) throws FrameGrabber.Exception {
|
//返回前端路径
|
// String vaddress = null;
|
// if (thread != null){
|
// thread.stop();
|
// //返回路径
|
// vaddress = "https://web.byisf.com/" + PRF_MINIO_URL + UUIDs + ".mp4";
|
// //把路径通过警情id添加到警情信息
|
// alarmService.updateVaddress(vaddress,uids,jid);
|
// return vaddress;
|
// }
|
xcbj = jid;
|
return "";
|
}
|
|
|
// /**
|
// * Javacv录制视频测试
|
// */
|
// @PostMapping("/cs")
|
// public void rVoids(String url,String uid) {
|
// String UUID = DateUtil.time();
|
// UUIDs=UUID;
|
// String newJson = StringEscapeUtils.unescapeHtml4(url);
|
// RecordVideoThread recordVideoThread = new RecordVideoThread(newJson,"D:\\software\\minio\\data\\jfpt\\void\\"+UUID +".mp4");
|
// thread = new Thread(recordVideoThread);
|
// thread.start();
|
// }
|
//
|
// @PostMapping("/csc")
|
// public String stopcs(String jid) throws FrameGrabber.Exception {
|
// //返回前端路径
|
// String vaddress = null;
|
// // 发出中断标志 true
|
// thread.interrupt();
|
// //返回路径
|
// vaddress = "https://web.byisf.com/" + PRF_MINIO_URL + UUIDs + ".mp4";
|
// //把路径通过警情id添加到警情信息
|
// String uids=Integer.toString(count);
|
// alarmService.updateVaddress(vaddress,uids,jid);
|
// return vaddress;
|
//
|
// }
|
|
|
|
}
|