Question : onSegment #71
Replies: 8 comments
-
Hello, what do you mean by segment? |
Beta Was this translation helpful? Give feedback.
-
Hi ! By segment, i meant the result of the segment muxer, as defined by ffmpeg. I wish to cut my stream in many small video files, and store them on the server machine. While waiting for your answer, i have started to experiment with the My explanation isn't the easiest to understand, so there's a graph to potentially make it easier to understand. I fear however, that once i start fetching the payloads from memory they won't be readable by ffmpeg and/or gstreamer (especially since they are limited in size to 1472 bytes as per my senders limitations). If you have insight, or ideas to upgrade this, then it would be strongly appreciated ! Graph
EDIT :i'd also like to extract the stream name (as defined in the URL : a stream on rtsps://url.com:8555/hello should send data with |
Beta Was this translation helpful? Give feedback.
-
For the question in the edit, a colleague and I found a solution. By shifting the import path to a local copy, you can then add a getter method in func (self *ServerSession) StreamName() *string {
return self.setuppedPath
} |
Beta Was this translation helpful? Give feedback.
-
Hello, in order to save the path name, it's enough to hook into func (sh *serverHandler) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*base.Response, *gortsplib.ServerStream, error) {
pathName = ctx.Path
return &base.Response{
StatusCode: base.StatusOK,
}, sh.stream, nil
} |
Beta Was this translation helpful? Give feedback.
-
Regarding the segments, first of all i'm assuming you're talking about a H264 video track.
Therefore, you have to do some work:
start with the var dec *rtph264.Decoder
func (sh *serverHandler) OnRecord(ctx *gortsplib.ServerHandlerOnRecordCtx) (*base.Response, error) {
// instantiate a RTP/H264 decoder
dec = rtph264.NewDecoder()
return &base.Response{
StatusCode: base.StatusOK,
}, nil
}
func (sh *serverHandler) OnFrame(ctx *gortsplib.ServerHandlerOnFrameCtx) {
if ctx.TrackID == h264Track {
// convert RTP frames into H264 NALUs
nalus, _, err := dec.Decode(ctx.Payload)
if err != nil {
return
}
for _, nalu := range nalus {
typ := nalu[0] & 0x1F
// we have an IDR frame and there isn't any existing buffer, or the current buffer is already of the desired duration
if typ == 5 && (thereIsNoBuffer || time.Since(lastBufferCreation) => period) {
// if there's an existing buffer, send it out and flush it
// allocate a new buffer and start filling it
} else {
// if there's an existing buffer, insert the non-IDR frame into it
}
}
}
} A very similar approach is used to convert from RTSP to HLS into rtsp-simple-server: https://github.com/aler9/rtsp-simple-server/blob/main/internal/hlsconverter/converter.go |
Beta Was this translation helpful? Give feedback.
-
I actually want to use h265, which is why i did not use the rtsp-simple-server, since they are more complex than h264. I will look into converting them. Do you have any good documentation for h265 i can read? I found none that were very indicative of how to handle this video format... |
Beta Was this translation helpful? Give feedback.
-
No sorry but work on H265 has to start yet. Only routing without decoding is supported. |
Beta Was this translation helpful? Give feedback.
-
Thanks. I feared it was the case, so I'll rely on ffmpeg + libx265 for now EDIT :For anyone in the future wondering, I'm planning on using this kind of code to pipe in/out of ffmpeg directly. In parrticular : cmd := exec.Command("ffmpeg", "-y", // Yes to all
//"-hide_banner", "-loglevel", "panic", // Hide all logs
"-i", "pipe:0", // take stdin as input
"-map_metadata", "-1", // strip out all (mostly) metadata
// conversion happens here
"-f", "mp3", // using mp3 muxer (IMPORTANT, output data to pipe require manual muxer selecting)
"pipe:1", // output to stdout
) I just need to plug libx265 into the mix to handle conversion |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi, I just wanted to know how one could run code for every segment (I'm trying to store the segments individually).
I think it would be possible to build something on top of onFrame, but I'm not sure whether the frame is actually the segment or really a frame of the video feed.
Thank you for your time
Beta Was this translation helpful? Give feedback.
All reactions