依赖 github.com/deepch/vdk 开源库

视频流生成图片部分 开源库使用cgo调用ffmpeg 需要安装对应的依赖软件

mac

brew install ffmpeg

ubuntu

apt install libavcodec-dev libavcodec-ffmpeg56 libavformat-dev libavformat-ffmpeg56
package main

import (
	"fmt"
	"github.com/deepch/vdk/av"
	"github.com/deepch/vdk/cgo/ffmpeg"
	"github.com/deepch/vdk/format/rtspv2"
	"image/jpeg"
	"log"
	"os"
	"time"
)

func main() {
	client, err := rtspv2.Dial(rtspv2.RTSPClientOptions{
		URL:              "rtsp://root:123456@127.0.0.1",
		Debug:            false,
		DisableAudio:     false,
		DialTimeout:      3 * time.Second,
		ReadWriteTimeout: 3 * time.Second,
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	defer client.Close()

	if client.CodecData == nil {
		return
	}

	AudioOnly := true
	var videoIDX int
	for i, codec := range client.CodecData {
		if codec.Type().IsVideo() {
			AudioOnly = false
            videoIDX = i
            break
		}
	}

	var FrameDecoderSingle *ffmpeg.VideoDecoder

	if !AudioOnly {
		FrameDecoderSingle, err = ffmpeg.NewVideoDecoder(client.CodecData[videoIDX].(av.VideoCodecData))
		if err != nil {
			log.Fatalln("FrameDecoderSingle Error", err)
		}
	}

	for {
		select {
		case signals := <-client.Signals:
			switch signals {
			case rtspv2.SignalStreamRTPStop:
				return
			default:
				fmt.Println("111", signals)
			}
		case packetAV := <-client.OutgoingPacketQueue:

			if packetAV.IsKeyFrame {
				if pic, err := FrameDecoderSingle.DecodeSingle(packetAV.Data); err == nil && pic != nil {
					if out, err := os.Create("./test.jpg"); err == nil {
						if err = jpeg.Encode(out, &pic.Image, nil); err == nil {
							log.Println("Poster Saved On Disk Ready ./output.jpg")
						}
					}
				}
			}
		}
	}
}