Fix frame.mp4 support
This commit is contained in:
+4
-10
@@ -35,7 +35,7 @@ func handlerKeyframe(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
exit := make(chan []byte)
|
exit := make(chan []byte)
|
||||||
|
|
||||||
cons := &mp4.Consumer{}
|
cons := &mp4.Keyframe{}
|
||||||
cons.Listen(func(msg interface{}) {
|
cons.Listen(func(msg interface{}) {
|
||||||
if data, ok := msg.([]byte); ok && exit != nil {
|
if data, ok := msg.([]byte); ok && exit != nil {
|
||||||
exit <- data
|
exit <- data
|
||||||
@@ -48,19 +48,13 @@ func handlerKeyframe(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
defer stream.RemoveConsumer(cons)
|
data := <-exit
|
||||||
|
|
||||||
w.Header().Set("Content-Type", cons.MimeType())
|
stream.RemoveConsumer(cons)
|
||||||
|
|
||||||
data, err := cons.Init()
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Caller().Send()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
data = append(data, <-exit...)
|
|
||||||
|
|
||||||
// Apple Safari won't show frame without length
|
// Apple Safari won't show frame without length
|
||||||
w.Header().Set("Content-Length", strconv.Itoa(len(data)))
|
w.Header().Set("Content-Length", strconv.Itoa(len(data)))
|
||||||
|
w.Header().Set("Content-Type", cons.MimeType)
|
||||||
|
|
||||||
if _, err := w.Write(data); err != nil {
|
if _, err := w.Write(data); err != nil {
|
||||||
log.Error().Err(err).Caller().Send()
|
log.Error().Err(err).Caller().Send()
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package mp4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/h264"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/h265"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
||||||
|
"github.com/pion/rtp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Keyframe struct {
|
||||||
|
streamer.Element
|
||||||
|
|
||||||
|
MimeType string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Keyframe) GetMedias() []*streamer.Media {
|
||||||
|
return []*streamer.Media{
|
||||||
|
{
|
||||||
|
Kind: streamer.KindVideo,
|
||||||
|
Direction: streamer.DirectionRecvonly,
|
||||||
|
Codecs: []*streamer.Codec{
|
||||||
|
{Name: streamer.CodecH264},
|
||||||
|
{Name: streamer.CodecH265},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Keyframe) AddTrack(media *streamer.Media, track *streamer.Track) *streamer.Track {
|
||||||
|
muxer := &Muxer{}
|
||||||
|
|
||||||
|
codecs := []*streamer.Codec{track.Codec}
|
||||||
|
|
||||||
|
init, err := muxer.GetInit(codecs)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c.MimeType = muxer.MimeType(codecs)
|
||||||
|
|
||||||
|
switch track.Codec.Name {
|
||||||
|
case streamer.CodecH264:
|
||||||
|
push := func(packet *rtp.Packet) error {
|
||||||
|
if !h264.IsKeyframe(packet.Payload) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := muxer.Marshal(0, packet)
|
||||||
|
c.Fire(append(init, buf...))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapper streamer.WrapperFunc
|
||||||
|
if track.Codec.IsMP4() {
|
||||||
|
wrapper = h264.RepairAVC(track)
|
||||||
|
} else {
|
||||||
|
wrapper = h264.RTPDepay(track)
|
||||||
|
}
|
||||||
|
push = wrapper(push)
|
||||||
|
|
||||||
|
return track.Bind(push)
|
||||||
|
|
||||||
|
case streamer.CodecH265:
|
||||||
|
push := func(packet *rtp.Packet) error {
|
||||||
|
if !h265.IsKeyframe(packet.Payload) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := muxer.Marshal(0, packet)
|
||||||
|
c.Fire(append(init, buf...))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !track.Codec.IsMP4() {
|
||||||
|
wrapper := h265.RTPDepay(track)
|
||||||
|
push = wrapper(push)
|
||||||
|
}
|
||||||
|
|
||||||
|
return track.Bind(push)
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("unsupported codec")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user