4 Commits

Author SHA1 Message Date
Andrey Semochkin
4b060bc442 fix dig 2024-02-08 01:00:12 +07:00
Andrey Semochkin
9f075c6682 fix hostShort / hostLong bug 2024-02-07 20:44:30 +07:00
Andrey Semochkin
0e06666006 fix listTag bug 2024-02-07 20:33:12 +07:00
deepch
b84c19f719 testing 2024-02-02 02:48:16 +03:00
6 changed files with 122 additions and 43 deletions

25
example/test/main.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"github.com/deepch/vdk/format/ts"
"log"
"os"
)
func main() {
f, _ := os.Open("edb9708f29b24ba9b175808d6b9df9c6541e25766d4a40209a8f903948b72f3f.ts")
m := ts.NewDemuxer(f)
var i int
for {
p, err := m.ReadPacket()
if err != nil {
return
}
if p.IsKeyFrame {
i = 0
}
log.Println(i, p.Time, p.Data[4:10], len(p.Data))
i++
}
}

View File

@@ -3,6 +3,7 @@ package mp4f
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"log"
"os" "os"
"time" "time"
@@ -238,14 +239,15 @@ func (self *Muxer) WriteTrailer() (err error) {
return return
} }
func (element *Muxer) WriteHeader(streams []av.CodecData) (err error) { func (element *Muxer) WriteHeader(streams []av.CodecData) error {
element.streams = []*Stream{} element.streams = []*Stream{}
for _, stream := range streams { for _, stream := range streams {
if err = element.newStream(stream); err != nil { if err := element.newStream(stream); err != nil {
return log.Println("WriteHeader", err)
} }
} }
return
return nil
} }
func (element *Muxer) GetInit(streams []av.CodecData) (string, []byte) { func (element *Muxer) GetInit(streams []av.CodecData) (string, []byte) {
@@ -285,6 +287,9 @@ func (element *Muxer) GetInit(streams []av.CodecData) (string, []byte) {
} }
func (element *Muxer) WritePacket(pkt av.Packet, GOP bool) (bool, []byte, error) { func (element *Muxer) WritePacket(pkt av.Packet, GOP bool) (bool, []byte, error) {
if pkt.Idx+1 > int8(len(element.streams)) {
return false, nil, nil
}
stream := element.streams[pkt.Idx] stream := element.streams[pkt.Idx]
if GOP { if GOP {
ts := time.Duration(0) ts := time.Duration(0)

View File

@@ -20,7 +20,13 @@ import (
) )
var MIME = []byte{11, 22, 111, 222, 11, 22, 111, 222} var MIME = []byte{11, 22, 111, 222, 11, 22, 111, 222}
var listTag = []string{"{server_id}", "{host_name}", "{host_name_short}", "{host_name_long}", "{stream_name}", "{channel_name}", "{stream_id}", "{channel_id}", "{start_year}", "{start_month}", "{start_day}", "{start_hour}", "{start_minute}", "{start_second}", "{start_millisecond}", "{start_unix_second}", "{start_unix_millisecond}", "{start_time}", "{start_pts}", "{end_year}", "{end_month}", "{end_day}", "{end_hour}", "{end_minute}", "{end_second}", "{end_millisecond}", "{start_unix_second}", "{start_unix_millisecond}", "{end_time}", "{end_pts}", "{duration_second}", "{duration_millisecond}"}
var listTag = []string{"{server_id}", "{host_name}", "{host_name_short}", "{host_name_long}",
"{stream_name}", "{channel_name}", "{stream_id}", "{channel_id}",
"{start_year}", "{start_month}", "{start_day}", "{start_hour}", "{start_minute}", "{start_second}",
"{start_millisecond}", "{start_unix_second}", "{start_unix_millisecond}", "{start_time}", "{start_pts}",
"{end_year}", "{end_month}", "{end_day}", "{end_hour}", "{end_minute}", "{end_second}",
"{end_millisecond}", "{end_unix_millisecond}", "{end_unix_second}", "{end_time}", "{end_pts}", "{duration_second}", "{duration_millisecond}"}
const ( const (
MP4 = "mp4" MP4 = "mp4"
@@ -28,20 +34,20 @@ const (
) )
type Muxer struct { type Muxer struct {
muxer *mp4.Muxer muxer *mp4.Muxer
format string format string
limit int limit int
d *os.File d *os.File
m *os.File m *os.File
dur time.Duration dur time.Duration
h int h int
gof *Gof gof *Gof
patch string patch string
mpoint []string mpoint []string
start, end time.Time start, end time.Time
pstart, pend time.Duration pstart, pend time.Duration
started bool started bool
serverID, streamName, channelName, streamID, channelID, hostname string serverID, streamName, channelName, streamID, channelID, hostLong, hostShort string
} }
type Gof struct { type Gof struct {
@@ -70,7 +76,11 @@ func init() {
} }
func NewMuxer(serverID, streamName, channelName, streamID, channelID string, mpoint []string, patch, format string, limit int) (m *Muxer, err error) { func NewMuxer(serverID, streamName, channelName, streamID, channelID string, mpoint []string, patch, format string, limit int) (m *Muxer, err error) {
hostname, _ := os.Hostname() hostLong, _ := os.Hostname()
var hostShort string
if p, _, ok := strings.Cut(hostLong, "."); ok {
hostShort = p
}
m = &Muxer{ m = &Muxer{
mpoint: mpoint, mpoint: mpoint,
patch: patch, patch: patch,
@@ -83,7 +93,8 @@ func NewMuxer(serverID, streamName, channelName, streamID, channelID string, mpo
channelName: channelName, channelName: channelName,
streamID: streamID, streamID: streamID,
channelID: channelID, channelID: channelID,
hostname: hostname, hostLong: hostLong,
hostShort: hostShort,
} }
return return
} }
@@ -247,11 +258,11 @@ func (m *Muxer) filePatch() (string, error) {
case "{server_id}": case "{server_id}":
ts = strings.Replace(ts, "{server_id}", m.serverID, -1) ts = strings.Replace(ts, "{server_id}", m.serverID, -1)
case "{host_name}": case "{host_name}":
ts = strings.Replace(ts, "{host_name}", m.hostname, -1) ts = strings.Replace(ts, "{host_name}", m.hostLong, -1)
case "{host_name_short}": case "{host_name_short}":
ts = strings.Replace(ts, "{host_name_short}", m.hostname, -1) ts = strings.Replace(ts, "{host_name_short}", m.hostShort, -1)
case "{host_name_long}": case "{host_name_long}":
ts = strings.Replace(ts, "{host_name_long}", m.hostname, -1) ts = strings.Replace(ts, "{host_name_long}", m.hostLong, -1)
case "{stream_name}": case "{stream_name}":
ts = strings.Replace(ts, "{stream_name}", m.streamName, -1) ts = strings.Replace(ts, "{stream_name}", m.streamName, -1)
case "{channel_name}": case "{channel_name}":
@@ -263,21 +274,21 @@ func (m *Muxer) filePatch() (string, error) {
case "{start_year}": case "{start_year}":
ts = strings.Replace(ts, "{start_year}", fmt.Sprintf("%d", m.start.Year()), -1) ts = strings.Replace(ts, "{start_year}", fmt.Sprintf("%d", m.start.Year()), -1)
case "{start_month}": case "{start_month}":
ts = strings.Replace(ts, "{start_month}", fmt.Sprintf("%d", int(m.start.Month())), -1) ts = strings.Replace(ts, "{start_month}", fmt.Sprintf("%02d", int(m.start.Month())), -1)
case "{start_day}": case "{start_day}":
ts = strings.Replace(ts, "{start_day}", fmt.Sprintf("%d", m.start.Day()), -1) ts = strings.Replace(ts, "{start_day}", fmt.Sprintf("%02d", m.start.Day()), -1)
case "{start_hour}": case "{start_hour}":
ts = strings.Replace(ts, "{start_hour}", fmt.Sprintf("%d", m.start.Hour()), -1) ts = strings.Replace(ts, "{start_hour}", fmt.Sprintf("%02d", m.start.Hour()), -1)
case "{start_minute}": case "{start_minute}":
ts = strings.Replace(ts, "{start_minute}", fmt.Sprintf("%d", m.start.Minute()), -1) ts = strings.Replace(ts, "{start_minute}", fmt.Sprintf("%02d", m.start.Minute()), -1)
case "{start_second}": case "{start_second}":
ts = strings.Replace(ts, "{start_second}", fmt.Sprintf("%d", m.start.Second()), -1) ts = strings.Replace(ts, "{start_second}", fmt.Sprintf("%02d", m.start.Second()), -1)
case "{start_millisecond}": case "{start_millisecond}":
ts = strings.Replace(ts, "{start_millisecond}", fmt.Sprintf("%d", m.start.Nanosecond()/1000/1000), -1) ts = strings.Replace(ts, "{start_millisecond}", fmt.Sprintf("%d", m.start.Nanosecond()/1000/1000), -1)
case "{start_unix_millisecond}": case "{start_unix_millisecond}":
ts = strings.Replace(ts, "{start_unix_millisecond}", fmt.Sprintf("%d", m.end.UnixMilli()), -1) ts = strings.Replace(ts, "{start_unix_millisecond}", fmt.Sprintf("%d", m.start.UnixMilli()), -1)
case "{start_unix_second}": case "{start_unix_second}":
ts = strings.Replace(ts, "{start_unix_second}", fmt.Sprintf("%d", m.end.Unix()), -1) ts = strings.Replace(ts, "{start_unix_second}", fmt.Sprintf("%d", m.start.Unix()), -1)
case "{start_time}": case "{start_time}":
ts = strings.Replace(ts, "{start_time}", fmt.Sprintf("%s", m.start.Format("2006-01-02T15:04:05-0700")), -1) ts = strings.Replace(ts, "{start_time}", fmt.Sprintf("%s", m.start.Format("2006-01-02T15:04:05-0700")), -1)
case "{start_pts}": case "{start_pts}":
@@ -285,17 +296,17 @@ func (m *Muxer) filePatch() (string, error) {
case "{end_year}": case "{end_year}":
ts = strings.Replace(ts, "{end_year}", fmt.Sprintf("%d", m.end.Year()), -1) ts = strings.Replace(ts, "{end_year}", fmt.Sprintf("%d", m.end.Year()), -1)
case "{end_month}": case "{end_month}":
ts = strings.Replace(ts, "{end_month}", fmt.Sprintf("%d", int(m.end.Month())), -1) ts = strings.Replace(ts, "{end_month}", fmt.Sprintf("%02d", int(m.end.Month())), -1)
case "{end_day}": case "{end_day}":
ts = strings.Replace(ts, "{end_day}", fmt.Sprintf("%d", m.end.Day()), -1) ts = strings.Replace(ts, "{end_day}", fmt.Sprintf("%02d", m.end.Day()), -1)
case "{end_hour}": case "{end_hour}":
ts = strings.Replace(ts, "{end_hour}", fmt.Sprintf("%d", m.end.Hour()), -1) ts = strings.Replace(ts, "{end_hour}", fmt.Sprintf("%02d", m.end.Hour()), -1)
case "{end_minute}": case "{end_minute}":
ts = strings.Replace(ts, "{end_minute}", fmt.Sprintf("%d", m.end.Minute()), -1) ts = strings.Replace(ts, "{end_minute}", fmt.Sprintf("%02d", m.end.Minute()), -1)
case "{end_second}": case "{end_second}":
ts = strings.Replace(ts, "{end_second}", fmt.Sprintf("%d", m.end.Second()), -1) ts = strings.Replace(ts, "{end_second}", fmt.Sprintf("%02d", m.end.Second()), -1)
case "{end_millisecond}": case "{end_millisecond}":
ts = strings.Replace(ts, "{end_millisecond}", fmt.Sprintf("%d", m.start.Nanosecond()/1000/1000), -1) ts = strings.Replace(ts, "{end_millisecond}", fmt.Sprintf("%d", m.end.Nanosecond()/1000/1000), -1)
case "{end_unix_millisecond}": case "{end_unix_millisecond}":
ts = strings.Replace(ts, "{end_unix_millisecond}", fmt.Sprintf("%d", m.end.UnixMilli()), -1) ts = strings.Replace(ts, "{end_unix_millisecond}", fmt.Sprintf("%d", m.end.UnixMilli()), -1)
case "{end_unix_second}": case "{end_unix_second}":

View File

@@ -40,9 +40,10 @@ const (
) )
type Client struct { type Client struct {
DebugRtsp bool DebugRtsp bool
DebugRtp bool DebugRtp bool
Headers []string DisableAudio bool
Headers []string
SkipErrRtpBlock bool SkipErrRtpBlock bool
@@ -1076,12 +1077,44 @@ func (self *Stream) handleRtpPacket(packet []byte) (err error) {
err = fmt.Errorf("rtp: packet too short") err = fmt.Errorf("rtp: packet too short")
return return
} }
payloadOffset := 12 + int(packet[0]&0xf)*4
timestamp := binary.BigEndian.Uint32(packet[4:8])
/*
Test offset
*/
Padding := (packet[0]>>5)&1 == 1
Extension := (packet[0]>>4)&1 == 1
CSRCCnt := int(packet[0] & 0x0f)
RTPHeaderSize := 12
payloadOffset := RTPHeaderSize
end := len(packet)
if end-payloadOffset >= 4*CSRCCnt {
payloadOffset += 4 * CSRCCnt
}
if Extension && end-payloadOffset >= 4 {
extLen := 4 * int(binary.BigEndian.Uint16(packet[payloadOffset+2:]))
payloadOffset += 4
if end-payloadOffset >= extLen {
payloadOffset += extLen
}
}
if Padding && end-payloadOffset > 0 {
paddingLen := int(packet[end-1])
if end-payloadOffset >= paddingLen {
end -= paddingLen
}
}
if payloadOffset > len(packet) { if payloadOffset > len(packet) {
err = fmt.Errorf("rtp: packet too short") err = fmt.Errorf("rtp: packet too short")
return return
} }
timestamp := binary.BigEndian.Uint32(packet[4:8])
payload := packet[payloadOffset:] payload := packet[payloadOffset:]
/* /*

1
format/rtsp/server.go Normal file
View File

@@ -0,0 +1 @@
package rtsp

View File

@@ -284,7 +284,11 @@ func (self *Stream) payloadEnd() (n int, err error) {
b := make([]byte, 4+len(nalu)) b := make([]byte, 4+len(nalu))
pio.PutU32BE(b[0:4], uint32(len(nalu))) pio.PutU32BE(b[0:4], uint32(len(nalu)))
copy(b[4:], nalu) copy(b[4:], nalu)
self.addPacket(b, time.Duration(0), (1000*time.Millisecond)/time.Duration(self.fps)) fps := self.fps
if self.fps == 0 {
fps = 25
}
self.addPacket(b, time.Duration(0), (1000*time.Millisecond)/time.Duration(fps))
n++ n++
} }
} }