Skip to content

Commit

Permalink
transcode: update profile name for rendition that matches the source …
Browse files Browse the repository at this point in the history
…stream's resolution (#157)

* transcode: update profile name for rendition that matches the source
stream's resolution

Remote B (via access-token) rejects transcode request if a profile with
name "source" is used. The "source" keyword is used to define an
incoming RTMP push in go-livepeer (server/mediaserver.go) - which
triggers a different use-case. Change the profile name to follow the
name syntax (e.g. 720p) being used for the other profiles.

* transcode: fix transcode test

* Update transcoded rendition folder names (#159)

* transcode: use nicer names for rendition folders

Instead of rendition-* folder names, use the profile name (e.g. 720p,
1080p, etc) as the folder name to make it more user friendly.

* transcode: fix failing tests
  • Loading branch information
emranemran committed Nov 8, 2022
1 parent dfbcf6f commit ccbb82b
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 20 deletions.
5 changes: 3 additions & 2 deletions transcode/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package transcode
import (
"fmt"
"net/url"
"path"
"path/filepath"
"sort"
"strings"
Expand Down Expand Up @@ -93,7 +94,7 @@ func GenerateAndUploadManifests(sourceManifest m3u8.MediaPlaylist, targetOSURL s
for i, profile := range transcodedStats {
// For each profile, add a new entry to the master manifest
masterPlaylist.Append(
fmt.Sprintf("rendition-%d/index.m3u8", i),
path.Join(profile.Name, "index.m3u8"),
&m3u8.MediaPlaylist{
TargetDuration: sourceManifest.TargetDuration,
},
Expand Down Expand Up @@ -128,7 +129,7 @@ func GenerateAndUploadManifests(sourceManifest m3u8.MediaPlaylist, targetOSURL s
renditionPlaylist.Close()

manifestFilename := "index.m3u8"
renditionManifestBaseURL := fmt.Sprintf("%s/rendition-%d", targetOSURL, i)
renditionManifestBaseURL := fmt.Sprintf("%s/%s", targetOSURL, profile.Name)
err = clients.UploadToOSURL(renditionManifestBaseURL, manifestFilename, strings.NewReader(renditionPlaylist.String()))
if err != nil {
return "", fmt.Errorf("failed to upload rendition playlist: %s", err)
Expand Down
16 changes: 8 additions & 8 deletions transcode/manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,16 @@ func TestItCanGenerateAndWriteManifests(t *testing.T) {
const expectedMasterManifest = `#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:PROGRAM-ID=0,BANDWIDTH=1,RESOLUTION=1080x720,NAME="0-super-high-def",FRAME-RATE=30.000
rendition-0/index.m3u8
super-high-def/index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=0,BANDWIDTH=1,RESOLUTION=800x600,NAME="1-lowlowlow",FRAME-RATE=60.000
rendition-1/index.m3u8
lowlowlow/index.m3u8
`
require.Equal(t, expectedMasterManifest, string(masterManifestContents))

// Confirm we wrote out the rendition manifests that we expected
require.FileExists(t, filepath.Join(outputDir, "rendition-0/index.m3u8"))
require.FileExists(t, filepath.Join(outputDir, "rendition-1/index.m3u8"))
require.NoFileExists(t, filepath.Join(outputDir, "rendition-2/index.m3u8"))
require.FileExists(t, filepath.Join(outputDir, "super-high-def/index.m3u8"))
require.FileExists(t, filepath.Join(outputDir, "lowlowlow/index.m3u8"))
require.NoFileExists(t, filepath.Join(outputDir, "small-high-def/index.m3u8"))
}

func TestCompliantMasterManifestOrdering(t *testing.T) {
Expand Down Expand Up @@ -193,11 +193,11 @@ func TestCompliantMasterManifestOrdering(t *testing.T) {
const expectedMasterManifest = `#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:PROGRAM-ID=0,BANDWIDTH=2000000,RESOLUTION=1080x720,NAME="0-super-high-def",FRAME-RATE=30.000
rendition-0/index.m3u8
super-high-def/index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=0,BANDWIDTH=2000000,RESOLUTION=800x600,NAME="1-small-high-def",FRAME-RATE=30.000
rendition-1/index.m3u8
small-high-def/index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=0,BANDWIDTH=1000000,RESOLUTION=800x600,NAME="2-lowlowlow",FRAME-RATE=60.000
rendition-2/index.m3u8
lowlowlow/index.m3u8
`
require.Equal(t, expectedMasterManifest, string(masterManifestContents))
}
7 changes: 5 additions & 2 deletions transcode/transcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"net/url"
"path"
"strconv"
"sync"
"time"

Expand Down Expand Up @@ -94,6 +95,8 @@ func RunTranscodeProcess(transcodeRequest TranscodeSegmentRequest, streamName st
}
// Go back to the root directory to set as the output for transcode renditions
targetTranscodedPath := path.Dir(path.Dir(segmentedOutputManifestURL.Path))

// Generate the rendition output URL (e.g. s3+https://USER:PASS@storage.googleapis.com/user/hls/)
tout, err := url.Parse(targetTranscodedPath)
if err != nil {
return outputs, fmt.Errorf("failed to parse targetTranscodedPath: %s", err)
Expand Down Expand Up @@ -218,7 +221,7 @@ func transcodeSegment(segment segmentInfo, streamName, manifestID string, transc
return fmt.Errorf("failed to find profile with name %q while parsing rendition segment", transcodedSegment.Name)
}

targetRenditionURL, err := url.JoinPath(targetOSURL.String(), fmt.Sprintf("rendition-%d/", renditionIndex))
targetRenditionURL, err := url.JoinPath(targetOSURL.String(), transcodedSegment.Name)
if err != nil {
return fmt.Errorf("error building rendition segment URL %q: %s", targetRenditionURL, err)
}
Expand Down Expand Up @@ -270,7 +273,7 @@ func getPlaybackProfiles(iv clients.InputVideo) ([]clients.EncodedProfile, error
profiles = []clients.EncodedProfile{lowBitrateProfile(video)}
}
profiles = append(profiles, clients.EncodedProfile{
Name: "source",
Name: strconv.FormatInt(int64(video.Height), 10) + "p0",
Bitrate: video.Bitrate,
FPS: 0,
Width: video.Width,
Expand Down
18 changes: 10 additions & 8 deletions transcode/transcode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http/httptest"
"os"
"path/filepath"
"strconv"
"testing"

"github.com/livepeer/catalyst-api/clients"
Expand Down Expand Up @@ -80,6 +81,10 @@ func TestItCanTranscode(t *testing.T) {
}))
defer callbackServer.Close()

sourceVideoTrack := clients.VideoTrack{
Width: 2020,
Height: 2020,
}
// Set up a fake Broadcaster that returns the rendition segments we'd expect based on the
// transcode request we send in the next step
localBroadcasterClient = StubBroadcasterClient{
Expand All @@ -90,7 +95,7 @@ func TestItCanTranscode(t *testing.T) {
MediaData: []byte("pretend media data"),
},
{
Name: "source",
Name: strconv.FormatInt(int64(sourceVideoTrack.Height), 10) + "p0",
MediaData: []byte("pretend high-def media data"),
},
},
Expand All @@ -110,11 +115,8 @@ func TestItCanTranscode(t *testing.T) {
SizeBytes: 123,
Tracks: []clients.InputTrack{
{
Type: "video",
VideoTrack: clients.VideoTrack{
Width: 2020,
Height: 2020,
},
Type: "video",
VideoTrack: sourceVideoTrack,
},
},
},
Expand All @@ -129,8 +131,8 @@ func TestItCanTranscode(t *testing.T) {
require.Contains(t, string(masterManifestBytes), "#EXT-X-STREAM-INF")

// Confirm that the master manifest contains links to 2 renditions
require.Contains(t, string(masterManifestBytes), "rendition-0/index.m3u8")
require.Contains(t, string(masterManifestBytes), "rendition-1/index.m3u8")
require.Contains(t, string(masterManifestBytes), "low-bitrate/index.m3u8")
require.Contains(t, string(masterManifestBytes), "2020p0/index.m3u8")

// Check we received a progress callback for each segment
require.Equal(t, 3, len(callbacks))
Expand Down

0 comments on commit ccbb82b

Please sign in to comment.