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?
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 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