使用Golang从S3流式传输HLS视频

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

Streaming HLS Video from S3 with Golang

问题

我想使用Go创建一个视频流服务器,用于提供存储在S3中的HLS视频(m3u8)。

以下是我的代码:

e.GET("/video", func(c echo.Context) error {
    // 下载m3u8文件
    buf := aws.NewWriteAtBuffer([]byte{})
    _, err := s3downloader.DownloadWithContext(ctx, buf, &s3.GetObjectInput{
        Bucket: aws.String(bucket),
        Key:    aws.String(objectKey), // hls/master.m3u8
    })

    return c.Stream(http.StatusOK, "application/x-mpegURL", bytes.NewReader(buf.Bytes()))
})

当我从Insomnia/postman执行localhost:1234/video时,它正确返回m3u8文件,与我直接执行S3 URL(https://xxx.s3.ap-southeast-1.amazonaws.com/xxx/hls/master.m3u8)的结果相同。

但是,当我从浏览器执行时,由我的Go服务器提供的视频无法播放,而S3服务器可以播放。

如何解决这个问题?

英文:

I want to create video streaming server that serve HLS video (m3u8) that is stored in S3 using Go.

Here is my code:

e.GET("/video", func(c echo.Context) error {
    // download file m3u8
	buf := aws.NewWriteAtBuffer([]byte{})
	_, err := s3downloader.DownloadWithContext(ctx, buf, &s3.GetObjectInput{
		Bucket: aws.String(bucket),
		Key:    aws.String(objectKey), // hls/master.m3u8
	})

	return c.Stream(http.StatusOK, "application/x-mpegURL", bytes.NewReader(buf.Bytes()))
})

When I execute localhost:1234/video from Insomnia/postman, it correctly returns m3u8 file, which is the same as I execute S3 URL directly (https://xxx.s3.ap-southeast-1.amazonaws.com/xxx/hls/master.m3u8)

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-STREAM-INF:BANDWIDTH=800800,RESOLUTION=640x360,CODECS="avc1.4d401e,mp4a.40.2"
360pixel/list.m3u8

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-STREAM-INF:BANDWIDTH=965800,RESOLUTION=854x480,CODECS="avc1.4d401f,mp4a.40.2"
480pixel/list.m3u8

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-STREAM-INF:BANDWIDTH=1267200,RESOLUTION=1280x720,CODECS="avc1.4d401f,mp4a.40.2"
720pixel/list.m3u8

But, when I execute from browser, the video that served by my golang server can't be played as the s3 server does.

How to solve this problem?

答案1

得分: 0

以下是翻译好的内容:

> 由我的 Golang 服务器提供的视频无法播放,因为 S3 服务器无法播放。

你的代码可能存在两个问题:

  1. Access-Control-Allow-Origin 头未设置为 *

    e.GET("/video", func(c echo.Context) error {
        // 下载 m3u8 文件
        buf := aws.NewWriteAtBuffer([]byte{})
        _, err := s3downloader.DownloadWithContext(ctx, buf, &s3.GetObjectInput{
            Bucket: aws.String(bucket),
            Key:    aws.String(objectKey), // hls/master.m3u8
        })
    
        c.Response().Header().Set(echo.HeaderAccessControlAllowOrigin, "*")
        return c.Stream(http.StatusOK, "application/x-mpegURL", bytes.NewReader(buf.Bytes()))
    })
    
  2. 以下路径是相对于原始请求的。如果主 m3u8 文件由你的 Golang 服务器提供,那么对嵌入的 m3u8 文件的请求将发送到你的 Golang 服务器。因此,你应该要么更改你的 Golang 服务器以提供嵌入的 m3u8 文件,要么将它们转换为绝对 URL(指向存储在 S3 中的对象)。

    ...
    360pixel/list.m3u8
    ...
    480pixel/list.m3u8
    ...
    720pixel/list.m3u8
    
英文:

> the video that served by my golang server can't be played as the s3 server does.

There could be two issues in your code:

  1. The Access-Control-Allow-Origin header is not set to *.

    e.GET("/video", func(c echo.Context) error {
    	// download file m3u8
    	buf := aws.NewWriteAtBuffer([]byte{})
    	_, err := s3downloader.DownloadWithContext(ctx, buf, &s3.GetObjectInput{
    		Bucket: aws.String(bucket),
    		Key:    aws.String(objectKey), // hls/master.m3u8
    	})
    
    	c.Response().Header().Set(echo.HeaderAccessControlAllowOrigin, "*")
    	return c.Stream(http.StatusOK, "application/x-mpegURL", bytes.NewReader(buf.Bytes()))
    })
    
  2. The following paths are relative to the original request. If the master m3u8 file is served by your golang server, the request to the embedded m3u8 file goes to your golang server. So you should either change your golang server to serve the embedded m3u8 files or convert them to absolute URLs (that points to the object stored in S3).

    ...
    360pixel/list.m3u8
    ...
    480pixel/list.m3u8
    ...
    720pixel/list.m3u8
    

huangapple
  • 本文由 发表于 2022年11月11日 10:58:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/74397580.html
匿名

发表评论

匿名网友

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

确定