pion / example-webrtc-applications

Examples of WebRTC applications that are large, or use 3rd party libraries
https://pion.ly/
MIT License
1.03k stars 243 forks source link

Snapshot continuously generates pictures by video frame #143

Closed lgcshy closed 10 months ago

lgcshy commented 10 months ago

Hello! I'd like to ask about the snapshot example about generating pictures. I plan to save every frame of the video stream from the camera to a directory on the server. Do I just need to use io. Writer writes bytes to os. File object is fine. Delete the return code below: `// Encode to (RGB) jpeg buffer := new(bytes.Buffer) if err = jpeg.Encode(buffer, img, nil); err != nil { panic(err) }

            // Serve image
            w.Header().Set("Content-Type", "image/jpeg")
            w.Header().Set("Content-Length", strconv.Itoa(len(buffer.Bytes())))

            // Write jpeg as HTTP Response
            if _, err = w.Write(buffer.Bytes()); err != nil {
                    panic(err)
            }
            return`
lgcshy commented 10 months ago

`func (t *TrackWriter) start() { for { pkt, _, err := t.track.ReadRTP() if err != nil { log.Println("read rtp error: ", err) break } t.sb.Push(pkt) // Use SampleBuilder to generate full picture from many RTP Packets sample := t.sb.Pop() if sample == nil { log.Println("sample is nil") continue }

    // Read VP8 header.
    videoKeyframe := (sample.Data[0]&0x1 == 0)
    if !videoKeyframe {
        log.Println("not video keyframe")
        continue
    }
    // Begin VP8-to-image decode: Init->DecodeFrameHeader->DecodeFrame
    t.decoder.Init(bytes.NewReader(sample.Data), len(sample.Data))

    // Decode header
    if _, err := t.decoder.DecodeFrameHeader(); err != nil {
        log.Println("decode frame header error: ", err)
        continue
    }

    // Decode Frame
    img, err := t.decoder.DecodeFrame()
    if err != nil {
        log.Println("decode frame error: ", err)
        continue
    }

    // Encode to (RGB) jpeg
    buffer := new(bytes.Buffer)
    if err = jpeg.Encode(buffer, img, &jpeg.Options{Quality: 100}); err != nil {
        log.Println("encode jpeg error: ", err)
        continue
    }
    // write to file
    fileName := fmt.Sprintf("%s-%s.jpg", t.track.Kind().String(), time.Now().Format("2006-01-02-15-04-05"))
    if err = os.WriteFile(fileName, buffer.Bytes(), 0644); err != nil {
        log.Println("write file error: ", err)
        continue
    }
}

}`

The above code can only get one picture, and then it will be judged that the keyframe is unsuccessful. My encoder is vp8 encoder

lgcshy commented 10 months ago

can anyone help