[*] 本地录像

This commit is contained in:
acgist
2023-06-02 07:17:10 +08:00
parent a06f6a251f
commit becc68b05f
19 changed files with 404 additions and 179 deletions

View File

@@ -10,10 +10,11 @@ import com.acgist.taoyao.boot.config.MediaAudioProperties;
import com.acgist.taoyao.boot.config.MediaVideoProperties;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.protocol.control.ControlBellProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlClientRecordProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlConfigAudioProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlConfigVideoProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlPhotographProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlRecordProtocol;
import com.acgist.taoyao.signal.protocol.control.ControlServerRecordProtocol;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -34,10 +35,11 @@ import lombok.RequiredArgsConstructor;
public class ControlController {
private final ControlBellProtocol controlBellProtocol;
private final ControlRecordProtocol controlRecordProtocol;
private final ControlPhotographProtocol controlPhotographProtocol;
private final ControlConfigAudioProtocol controlConfigAudioProtocol;
private final ControlConfigVideoProtocol controlConfigVideoProtocol;
private final ControlClientRecordProtocol controlClientRecordProtocol;
private final ControlServerRecordProtocol controlServerRecordProtocol;
@Operation(summary = "响铃", description = "响铃控制")
@GetMapping("/bell/{clientId}")
@@ -45,10 +47,16 @@ public class ControlController {
return this.controlBellProtocol.execute(clientId, enabled);
}
@Operation(summary = "录像", description = "录像控制")
@GetMapping("/record/{clientId}")
@Operation(summary = "录像", description = "终端录像控制")
@GetMapping("/client/record/{clientId}")
public Message record(@PathVariable String clientId, @NotNull(message = "没有指定操作状态") Boolean enabled) {
return this.controlRecordProtocol.execute(clientId, enabled);
return this.controlClientRecordProtocol.execute(clientId, enabled);
}
@Operation(summary = "录像", description = "服务端录像控制")
@GetMapping("/server/record/{roomId}/{clientId}")
public Message record(@PathVariable String roomId, @PathVariable String clientId, @NotNull(message = "没有指定操作状态") Boolean enabled) {
return this.controlServerRecordProtocol.execute(roomId, clientId, enabled);
}
@Operation(summary = "拍照", description = "拍照控制")

View File

@@ -1,37 +0,0 @@
package com.acgist.taoyao.controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.protocol.media.MediaRecordProtocol;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
/**
* 媒体
*
* @author acgist
*/
@Tag(name = "媒体", description = "媒体管理")
@Validated
@RestController
@RequestMapping("/media")
@RequiredArgsConstructor
public class MediaController {
private final MediaRecordProtocol mediaRecordProtocol;
@Operation(summary = "录像", description = "媒体录像")
@GetMapping("/record/{roomId}/{clientId}")
public Message record(@PathVariable String roomId, @PathVariable String clientId, @NotNull(message = "没有指定操作状态") Boolean enabled) {
return this.mediaRecordProtocol.execute(roomId, clientId, enabled);
}
}

View File

@@ -228,17 +228,17 @@ taoyao:
# SDPVP8 | H264
sdp: |
v=0
o=- 0 0 IN IP4 %s
o=- 0 0 IN IP4 127.0.0.1
s=TaoyaoRecord
t=0 0
m=audio %d RTP/AVP 97
c=IN IP4 %s
a=rtpmap:97 OPUS/48000/2
a=fmtp:97 sprop-stereo=1
m=video %d RTP/AVP 96
c=IN IP4 %s
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1
m=audio %d RTP/AVP 100
c=IN IP4 127.0.0.1
a=rtpmap:100 OPUS/48000/2
a=fmtp:100 sprop-stereo=1
m=video %d RTP/AVP 107
c=IN IP4 127.0.0.1
a=rtpmap:107 H264/90000
a=fmtp:107 packetization-mode=1
# 录像命令
record: ffmpeg -protocol_whitelist "file,rtp,udp" -y -i %s %s
# 截图命令
@@ -252,7 +252,8 @@ taoyao:
# 视频存储目录
storage-video-path: /data/taoyao/storage/video
# 录像地址
host: 127.0.0.1
#host: 127.0.0.1
host: 192.168.8.40
# 端口范围
min-port: 50000
max-port: 59999

View File

@@ -25,13 +25,27 @@ public class RecorderTest {
a=fmtp:97 sprop-stereo=1
m=video %d RTP/AVP 96
c=IN IP4 %s
a=rtpmap:96 H264/90000
a=rtpmap:96 VP8/90000
a=fmtp:96 packetization-mode=1
""");
// ffmpegProperties.setSdp("""
// v=0
// o=- 0 0 IN IP4 %s
// s=TaoyaoRecord
// t=0 0
// m=audio %d RTP/AVP 97
// c=IN IP4 %s
// a=rtpmap:97 OPUS/48000/2
// a=fmtp:97 sprop-stereo=1
// m=video %d RTP/AVP 96
// c=IN IP4 %s
// a=rtpmap:96 H264/90000
// a=fmtp:96 packetization-mode=1
// """);
ffmpegProperties.setRecord("ffmpeg -protocol_whitelist \"file,rtp,udp\" -y -i %s %s");
ffmpegProperties.setPreview("ffmpeg -y -i %s -ss %d -vframes 1 -f image2 %s");
ffmpegProperties.setDuration("ffprobe -i %s -show_entries format=duration");
final Recorder recorder = new Recorder("taoyao", ffmpegProperties);
final Recorder recorder = new Recorder("taoyao", null, null, ffmpegProperties);
recorder.start();
Thread.sleep(20 * 1000);
recorder.stop();