英文:
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 服务器无法播放。
你的代码可能存在两个问题:
-
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())) })
-
以下路径是相对于原始请求的。如果主
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:
-
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())) })
-
The following paths are relative to the original request. If the master
m3u8
file is served by your golang server, the request to the embeddedm3u8
file goes to your golang server. So you should either change your golang server to serve the embeddedm3u8
files or convert them to absolute URLs (that points to the object stored in S3).... 360pixel/list.m3u8 ... 480pixel/list.m3u8 ... 720pixel/list.m3u8
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论