mirror of
https://github.com/Monibuca/plugin-record.git
synced 2025-10-18 06:31:00 +08:00
90 lines
2.3 KiB
Go
90 lines
2.3 KiB
Go
package record
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
. "github.com/Monibuca/engine/v3"
|
|
. "github.com/Monibuca/utils/v3"
|
|
"github.com/Monibuca/utils/v3/codec"
|
|
)
|
|
|
|
func getDuration(file *os.File) uint32 {
|
|
_, err := file.Seek(-4, io.SeekEnd)
|
|
if err == nil {
|
|
var tagSize uint32
|
|
if tagSize, err = ReadByteToUint32(file, true); err == nil {
|
|
_, err = file.Seek(-int64(tagSize)-4, io.SeekEnd)
|
|
if err == nil {
|
|
_, timestamp, _, err := codec.ReadFLVTag(file)
|
|
if err == nil {
|
|
return timestamp
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
func SaveFlv(streamPath string, append bool) error {
|
|
flag := os.O_CREATE
|
|
if append {
|
|
flag = flag | os.O_RDWR | os.O_APPEND
|
|
} else {
|
|
flag = flag | os.O_TRUNC | os.O_WRONLY
|
|
}
|
|
filePath := filepath.Join(config.Path, streamPath+".flv")
|
|
if err := os.MkdirAll(filepath.Dir(filePath), 0755); err != nil {
|
|
return err
|
|
}
|
|
file, err := os.OpenFile(filePath, flag, 0755)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// return avformat.WriteFLVTag(file, packet)
|
|
p := Subscriber{
|
|
ID: filePath,
|
|
Type: "FlvRecord",
|
|
ByteStreamFormat: true,
|
|
}
|
|
var offsetTime uint32
|
|
if append {
|
|
offsetTime = getDuration(file)
|
|
file.Seek(0, io.SeekEnd)
|
|
} else {
|
|
_, err = file.Write(codec.FLVHeader)
|
|
}
|
|
if err == nil {
|
|
recordings.Store(filePath, &p)
|
|
if err := p.Subscribe(streamPath); err == nil {
|
|
vt, at := p.WaitVideoTrack(), p.WaitAudioTrack()
|
|
p.OnAudio = func(audio AudioPack) {
|
|
if !append && at.CodecID == 10 { //AAC格式需要发送AAC头
|
|
codec.WriteFLVTag(file, codec.FLV_TAG_TYPE_AUDIO, 0, at.ExtraData)
|
|
}
|
|
codec.WriteFLVTag(file, codec.FLV_TAG_TYPE_AUDIO, audio.Timestamp+offsetTime, audio.Payload)
|
|
p.OnAudio = func(audio AudioPack) {
|
|
codec.WriteFLVTag(file, codec.FLV_TAG_TYPE_AUDIO, audio.Timestamp+offsetTime, audio.Payload)
|
|
}
|
|
}
|
|
p.OnVideo = func(video VideoPack) {
|
|
if !append {
|
|
codec.WriteFLVTag(file, codec.FLV_TAG_TYPE_VIDEO, 0, vt.ExtraData.Payload)
|
|
}
|
|
codec.WriteFLVTag(file, codec.FLV_TAG_TYPE_VIDEO, video.Timestamp+offsetTime, video.Payload)
|
|
p.OnVideo = func(video VideoPack) {
|
|
codec.WriteFLVTag(file, codec.FLV_TAG_TYPE_VIDEO, video.Timestamp+offsetTime, video.Payload)
|
|
}
|
|
}
|
|
go func() {
|
|
p.Play(at, vt)
|
|
file.Close()
|
|
}()
|
|
}
|
|
|
|
} else {
|
|
file.Close()
|
|
}
|
|
return err
|
|
}
|