diff --git a/handlers/misttriggers/recording_end.go b/handlers/misttriggers/recording_end.go index dd23b62a9..ef5f6321c 100644 --- a/handlers/misttriggers/recording_end.go +++ b/handlers/misttriggers/recording_end.go @@ -97,7 +97,7 @@ func (d *MistCallbackHandlersCollection) triggerRecordingEndSegmenting(w http.Re } go func() { - err := transcode.RunTranscodeProcess(transcodeRequest, p.StreamName, p.StreamMediaDurationMillis) + err := transcode.RunTranscodeProcess(transcodeRequest, p.StreamName) if err != nil { _ = config.Logger.Log( "msg", "RunTranscodeProcess returned an error", diff --git a/handlers/transcode.go b/handlers/transcode.go index 43f09d822..76e9e84cc 100644 --- a/handlers/transcode.go +++ b/handlers/transcode.go @@ -37,7 +37,7 @@ func (d *CatalystAPIHandlersCollection) TranscodeSegment() httprouter.Handle { // TODO: Do this asynchronously and pass valid stream-name and input file duration // when the transcode api endpoint is accessed (only used for testing for now) - err = transcode.RunTranscodeProcess(transcodeRequest, "", 0) + err = transcode.RunTranscodeProcess(transcodeRequest, "") if err != nil { errors.WriteHTTPInternalServerError(w, "Error running Transcode process", err) } diff --git a/transcode/manifest.go b/transcode/manifest.go index 2e0389e7b..0ac9cc7c9 100644 --- a/transcode/manifest.go +++ b/transcode/manifest.go @@ -36,9 +36,14 @@ func DownloadRenditionManifest(sourceManifestOSURL string) (m3u8.MediaPlaylist, return *mediaPlaylist, nil } +type SourceSegment struct { + URL string + DurationMillis int64 +} + // Loop over each segment and convert it from a relative to a full ObjectStore-compatible URL -func GetSourceSegmentURLs(sourceManifestURL string, manifest m3u8.MediaPlaylist) ([]string, error) { - var urls []string +func GetSourceSegmentURLs(sourceManifestURL string, manifest m3u8.MediaPlaylist) ([]SourceSegment, error) { + var urls []SourceSegment for _, segment := range manifest.Segments { // The segments list is a ring buffer - see https://github.com/grafov/m3u8/issues/140 // and so we only know we've hit the end of the list when we find a nil element @@ -50,7 +55,13 @@ func GetSourceSegmentURLs(sourceManifestURL string, manifest m3u8.MediaPlaylist) if err != nil { return nil, err } - urls = append(urls, u) + urls = append( + urls, + SourceSegment{ + URL: u, + DurationMillis: int64(segment.Duration * 1000), + }, + ) } return urls, nil diff --git a/transcode/manifest_test.go b/transcode/manifest_test.go index 234e361d8..1230a8134 100644 --- a/transcode/manifest_test.go +++ b/transcode/manifest_test.go @@ -76,6 +76,23 @@ func TestItCanConvertRelativeURLsToOSURLs(t *testing.T) { require.Equal(t, "s3+https://REDACTED:REDACTED@storage.googleapis.com/something/001.ts", u) } +func TestItParsesManifestAndConvertsRelativeURLs(t *testing.T) { + sourceManifest, _, err := m3u8.DecodeFrom(strings.NewReader(validMediaManifest), true) + require.NoError(t, err) + + sourceMediaManifest, ok := sourceManifest.(*m3u8.MediaPlaylist) + require.True(t, ok) + + us, err := GetSourceSegmentURLs("s3+https://REDACTED:REDACTED@storage.googleapis.com/something/output.m3u8", *sourceMediaManifest) + require.NoError(t, err) + + require.Equal(t, 2, len(us)) + require.Equal(t, "s3+https://REDACTED:REDACTED@storage.googleapis.com/something/0.ts", us[0].URL) + require.Equal(t, int64(10416), us[0].DurationMillis) + require.Equal(t, "s3+https://REDACTED:REDACTED@storage.googleapis.com/something/5000.ts", us[1].URL) + require.Equal(t, int64(5334), us[1].DurationMillis) +} + func TestItCanGenerateAndWriteManifests(t *testing.T) { // Set up the parameters we pass in sourceManifest, _, err := m3u8.DecodeFrom(strings.NewReader(validMediaManifest), true) diff --git a/transcode/transcode.go b/transcode/transcode.go index 9a6f47ac8..1bd1942ce 100644 --- a/transcode/transcode.go +++ b/transcode/transcode.go @@ -55,7 +55,7 @@ func init() { localBroadcasterClient = b } -func RunTranscodeProcess(transcodeRequest TranscodeSegmentRequest, streamName string, durationMillis int64) error { +func RunTranscodeProcess(transcodeRequest TranscodeSegmentRequest, streamName string) error { _ = config.Logger.Log("msg", "RunTranscodeProcess (v2) Beginning", "source", transcodeRequest.SourceFile, "target", transcodeRequest.UploadURL) // Create a separate subdirectory for the transcoded renditions @@ -94,7 +94,7 @@ func RunTranscodeProcess(transcodeRequest TranscodeSegmentRequest, streamName st // Iterate through the segment URLs and transcode them // TODO: Some level of parallelisation once we're happy this works well for segmentIndex, u := range sourceSegmentURLs { - rc, err := clients.DownloadOSURL(u) + rc, err := clients.DownloadOSURL(u.URL) if err != nil { return fmt.Errorf("failed to download source segment %q: %s", u, err) } @@ -108,14 +108,14 @@ func RunTranscodeProcess(transcodeRequest TranscodeSegmentRequest, streamName st } broadcasterClient, _ := clients.NewRemoteBroadcasterClient(creds) - tr, err := broadcasterClient.TranscodeSegmentWithRemoteBroadcaster(rc, int64(segmentIndex), transcodeProfiles, streamName, durationMillis) + tr, err := broadcasterClient.TranscodeSegmentWithRemoteBroadcaster(rc, int64(segmentIndex), transcodeProfiles, streamName, u.DurationMillis) if err != nil { return fmt.Errorf("failed to run TranscodeSegmentWithRemoteBroadcaster: %s", err) } fmt.Println("transcodeResult", tr) //remove this // TODO: Upload the output segments } else { - tr, err := localBroadcasterClient.TranscodeSegment(rc, int64(segmentIndex), transcodeProfiles, durationMillis) + tr, err := localBroadcasterClient.TranscodeSegment(rc, int64(segmentIndex), transcodeProfiles, u.DurationMillis) if err != nil { return fmt.Errorf("failed to run TranscodeSegment: %s", err) } diff --git a/transcode/transcode_test.go b/transcode/transcode_test.go index 57fcc1dbc..8b8859f83 100644 --- a/transcode/transcode_test.go +++ b/transcode/transcode_test.go @@ -108,7 +108,6 @@ func TestItCanTranscode(t *testing.T) { UploadURL: manifestFile.Name(), }, "streamName", - 123, ) require.NoError(t, err)