有没有一种方法可以提供视频的开始和结束时间(以秒为单位)?

huangapple go评论69阅读模式
英文:

Is there a way to serve the video part, providing start end seconds?

问题

我正在尝试使用后端来提供存储中的视频。我使用Go + GIN,它可以工作,但我需要实现带有开始和结束参数的视频请求。例如,我有一个持续10分钟的视频,我想请求从2分钟到3分钟的片段。这是否可能?是否有示例可供参考?

以下是您目前的代码:

accessKeyID := ""
secretAccessKey := ""
useSSL := false

ctx := context.Background()
endpoint := "127.0.0.1:9000"
bucketName := "mybucket"

// 初始化 minio 客户端对象
minioClient, err := minio.New(endpoint, &minio.Options{
    Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
    Secure: useSSL,
})
if err != nil {
    log.Fatalln(err)
}

// 获取文件
object, err := minioClient.GetObject(ctx, bucketName, "1.mp4", minio.GetObjectOptions{})
if err != nil {
    fmt.Println(err)
    return
}
objInfo, err := object.Stat()
if err != nil {
    return
}

buffer := make([]byte, objInfo.Size)
object.Read(buffer)

c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", objInfo.Size))
c.Writer.Header().Set("Content-Type", "video/mp4")
c.Writer.Header().Set("Connection", "keep-alive")
c.Writer.Header().Set("Content-Range", fmt.Sprintf("bytes 0-%d/%d", objInfo.Size, objInfo.Size))

//c.Writer.Write(buffer)
c.DataFromReader(200, objInfo.Size, "video/mp4", bytes.NewReader(buffer), nil)

希望对您有所帮助!

英文:

I am trying to use the backend to serve the video from the storage. I use Go + GIN It works but I need to implement video requests with start and end parameters. For example, I have a video with 10 mins duration and I want to request a fragment from 2 to 3 mins. Is it possible or are there examples somewhere?

This is what I have now:

accessKeyID := ""
secretAccessKey := ""
useSSL := false

ctx := context.Background()
endpoint := "127.0.0.1:9000"
bucketName := "mybucket"

// Initialize minio client object.
minioClient, err := minio.New(endpoint, &minio.Options{
	Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
	Secure: useSSL,
})
if err != nil {
	log.Fatalln(err)
}

// Get file
object, err := minioClient.GetObject(ctx, bucketName, "1.mp4", minio.GetObjectOptions{})
if err != nil {
	fmt.Println(err)
	return
}
objInfo, err := object.Stat()
if err != nil {
	return
}

buffer := make([]byte, objInfo.Size)
object.Read(buffer)

c.Writer.Header().Set("Content-Length", fmt.Sprintf("%d", objInfo.Size))
c.Writer.Header().Set("Content-Type", "video/mp4")
c.Writer.Header().Set("Connection", "keep-alive")
c.Writer.Header().Set("Content-Range", fmt.Sprintf("bytes 0-%d/%d", objInfo.Size, objInfo.Size))

//c.Writer.Write(buffer)
c.DataFromReader(200, objInfo.Size, "video/mp4", bytes.NewReader(buffer), nil)

答案1

得分: 2

这将需要你的程序至少对媒体流进行解复用,以获取其中的时间信息,以防你使用的容器支持该功能;或者在不支持的情况下,实际解码视频流。一般来说,你无法知道需要在视频文件中寻找多少字节才能到达特定位置。

由于输出需要是一个有效的媒体容器,以便请求者能够处理它,所以需要将其重新混合到输出容器中。

因此,选择一个能够完成这些操作的库,并阅读其文档。Ffmpeg / avlib 是经典选择,但我不知道是否已经有其他人为其编写了go绑定。如果没有,编写绑定可能是值得的。


注:在某些情况下,你可能可以知道需要寻找多少字节,这可能适用于具有固定复用比特率的MPEG传输流。但除非你从事实际的电视塔或电视卫星的视频流媒体工作,需要一个恒定速率的数据流,否则你可能不会处理这些情况。

英文:

This will require your program to at least demux the media stream to get time information out of it, in case you're using a container that supports that, or to actually decode the video stream in case it doesn't - in general, you can't know how many bytes you need to seek into a video file to go to a specific location¹.

As the output again needs to be a valid media container so that whoever requested it can deal with it, there's going to be remixing into an output container.

So, pick yourself a library that can do that and read its documentation. Ffmpeg / avlib is the classical choice there, but I have positively no idea about whether someone else has already written go bindings for it. If not, doing that works be worthwhile.


¹ there is cases where you can, that would probably apply to MPEG Transport Streams with a fixed mux bitrate. But unless you're working in streaming of video for actual TV towers or actual TV satellites that need a constant rate data stream, you will not likely be dealing with these

huangapple
  • 本文由 发表于 2023年1月24日 17:01:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75219328.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定