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"
@@ -41,7 +47,7 @@ type Muxer struct {
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

@@ -42,6 +42,7 @@ const (
type Client struct { type Client struct {
DebugRtsp bool DebugRtsp bool
DebugRtp bool DebugRtp bool
DisableAudio bool
Headers []string 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++
} }
} }