Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

获取rtsp流,保存mp4文件。生成的文件不能显示视频,但能显示时间。请问这是怎么回事?代码如下 #90

Open
moonfdd opened this issue Oct 26, 2023 · 3 comments

Comments

@moonfdd
Copy link

moonfdd commented Oct 26, 2023

package main

import (
	"fmt"
	"os"
	"time"

	"github.com/deepch/vdk/format/mp4"
	"github.com/deepch/vdk/format/rtspv2"
)

func main() {
	c, err := rtspv2.Dial(rtspv2.RTSPClientOptions{URL: "rtsp://admin:[email protected]:554/LiveMedia/ch1/Media2", DisableAudio: true, DialTimeout: 3 * time.Second, ReadWriteTimeout: 3 * time.Second, Debug: false})
	if err != nil {
		fmt.Println("失败", err)
		return
	}
	defer c.Close()
	fmt.Println("连接成功")
	fmt.Println(c.CodecData[0].Type())

	f, err2 := os.Create("./test.mp4")
	if err2 != nil {
		fmt.Println("创建文件失败", err2)
		return
	}
	defer f.Close()

	m := mp4.NewMuxer(f)
	err = m.WriteHeader(c.CodecData)
	if err != nil {
		fmt.Println("WriteHeader失败", err)
		return
	} else {
		fmt.Println("WriteHeader成功")
	}
	i := 0
	for {
		select {
		case signals := <-c.Signals:
			fmt.Println("信号:", signals)
			switch signals {
			case rtspv2.SignalCodecUpdate:
				fmt.Println("开始")

			case rtspv2.SignalStreamRTPStop:
				return
			}
		case packetAV := <-c.OutgoingPacketQueue:
			fmt.Println("数据:", packetAV.IsKeyFrame, i)
			i++
			err = m.WritePacket(*packetAV)
			if err != nil {
				fmt.Println("WritePacket失败", err)
				return
			} else {
				fmt.Println(packetAV.CompositionTime)
				fmt.Println(packetAV.Duration)
				fmt.Println(packetAV.Idx)
				fmt.Println(packetAV.IsKeyFrame)
				fmt.Println(packetAV.Time)
				fmt.Println("WritePacket成功", len(packetAV.Data))
			}
		}
		if i >= 251 {
			break
		}
	}
	m.WriteTrailer()
	fmt.Println("WriteTrailer成功")
	fmt.Println("结束")

	fmt.Println("")
}

image
image

用vlc播放视频文件,看不到画面,但能看到时间。看文件大小,明显不对。是不是代码写得有问题?谢谢了。

@yupeng2015
Copy link

我也遇到这个问题了,请问楼主解决了么 @moonfdd

@moonfdd
Copy link
Author

moonfdd commented Jul 22, 2024

我也遇到这个问题了,请问楼主解决了么 @moonfdd

解决了,要先获取码流,再WriteHeader。

`
c, err := rtspv2.Dial(rtspv2.RTSPClientOptions{URL: this.RtspMax, DisableAudio: true, DialTimeout: 3 * time.Second, ReadWriteTimeout: time.Second, Debug: false})

				for {
					isbreak := false
					select {
					case signals := <-c.Signals:
						switch signals {
						case rtspv2.SignalStreamRTPStop:
							isbreak = true
						}
					case packetAV := <-c.OutgoingPacketQueue:
						if i == 0 {
							err = m.WriteHeader(c.CodecData)
							if err != nil {
								return
							}
							start = time.Now()
						}
						i++
						err = m.WritePacket(*packetAV)
						if err != nil {
							isbreak = true
						}
					}
					if i >= NumberOfFrames || isbreak || isClose {
						break
					}
				}

`

这代码不完整,凑合着看看吧。如果直接WriteHeader,c.CodecData是空的。获取码流,再WriteHeader,c.CodecData就有数据了。

@yupeng2015
Copy link

我昨晚又调试了一下,发现按照官方demo写入CodecData是可以的,是我这边保存流不当导致播放异常。我这边对流媒体不是很熟,也是参照你的代码才成功的,多谢了 @moonfdd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants