Skip to content

Commit

Permalink
Stub "Transcode Complete" callback (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomshutt committed Sep 7, 2022
1 parent 1753b3b commit f8d600f
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 8 deletions.
98 changes: 90 additions & 8 deletions clients/callback_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,33 @@ func (c CallbackClient) SendTranscodeStatusError(callbackURL, errorMsg string) e
return c.DoWithRetries(r)
}

// Separate method as this requires a much richer message than the other status callbacks
func (c CallbackClient) SendTranscodeStatusCompleted(url string, iv InputVideo, ov []OutputVideo) error {
tsm := TranscodeStatusCompletedMessage{
TranscodeStatusMessage: TranscodeStatusMessage{
CompletionRatio: overallCompletionRatio(TranscodeStatusCompleted, 1),
Status: TranscodeStatusCompleted.String(),
Timestamp: config.Clock.GetTimestampUTC(),
},
Type: "video", // Assume everything is a video for now
InputVideo: iv,
Outputs: ov,
}

j, err := json.Marshal(tsm)
if err != nil {
return err
}

r, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(j))
if err != nil {
return err
}

return c.DoWithRetries(r)

}

// Calculate the overall completion ratio based on the completion ratio of the current stage.
// The weighting will need to be tweaked as we understand better the relative time spent in the
// segmenting vs. transcoding stages.
Expand Down Expand Up @@ -134,14 +161,6 @@ const (
TranscodeStatusError
)

type TranscodeStatusMessage struct {
CompletionRatio float64 `json:"completion_ratio"` // No omitempty or we lose this for 0% completion case
Error string `json:"error,omitempty"`
Retriable *bool `json:"retriable,omitempty"` // Has to be a pointer or we can't differentiate omission from 'false'
Status string `json:"status,omitempty"`
Timestamp int64 `json:"timestamp"`
}

func (ts TranscodeStatus) String() string {
switch ts {
case TranscodeStatusPreparing:
Expand All @@ -157,3 +176,66 @@ func (ts TranscodeStatus) String() string {
}
return "unknown"
}

// The various status messages we can send

type TranscodeStatusMessage struct {
CompletionRatio float64 `json:"completion_ratio"` // No omitempty or we lose this for 0% completion case
Error string `json:"error,omitempty"`
Unretriable bool `json:"unretriable,omitempty"`
Status string `json:"status"`
Timestamp int64 `json:"timestamp"`
}

type VideoTrack struct {
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
PixelFormat string `json:"pixel_format,omitempty"`
FPS int `json:"fps,omitempty"`
}

type AudioTrack struct {
Channels int `json:"channels,omitempty"`
SampleRate int `json:"sample_rate,omitempty"`
}

type InputTrack struct {
Type string `json:"type"`
Codec string `json:"codec"`
Bitrate int `json:"bitrate"`
DurationSec float64 `json:"duration"`
SizeBytes int `json:"size"`
StartTimeSec float64 `json:"start_time"`

// Fields only used if this is a Video Track
VideoTrack

// Fields only used if this is an Audio Track
AudioTrack
}

type InputVideo struct {
Format string `json:"format"`
Tracks []InputTrack `json:"tracks"`
Duration float64 `json:"duration"`
SizeBytes int `json:"size"`
}

type OutputVideoFile struct {
Type string `json:"type"`
SizeBytes int `json:"size"`
Location string `json:"location"`
}

type OutputVideo struct {
Type string `json:"type"`
Manifest string `json:"manifest"`
Videos []OutputVideoFile `json:"videos"`
}

type TranscodeStatusCompletedMessage struct {
TranscodeStatusMessage
Type string `json:"type"`
InputVideo InputVideo `json:"video_spec"`
Outputs []OutputVideo `json:"outputs"`
}
59 changes: 59 additions & 0 deletions handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,5 +207,64 @@ func (d *MistCallbackHandlersCollection) Trigger() httprouter.Handle {

// TODO: add timeout for the stream upload
// TODO: start transcoding
stubTranscodingCallbacksForStudio(d.StreamCache[s].callbackUrl, callbackClient)
}
}

// This method is for Studio to have something to integrate with and to make sure we have all the callbacks
// in place that we'll need
func stubTranscodingCallbacksForStudio(callbackURL string, callbackClient clients.CallbackClient) {
time.Sleep(5 * time.Second)
callbackClient.SendTranscodeStatus(callbackURL, clients.TranscodeStatusTranscoding, 0.3)
time.Sleep(5 * time.Second)
callbackClient.SendTranscodeStatus(callbackURL, clients.TranscodeStatusTranscoding, 0.6)
time.Sleep(5 * time.Second)
callbackClient.SendTranscodeStatus(callbackURL, clients.TranscodeStatusTranscoding, 0.9)
time.Sleep(5 * time.Second)
callbackClient.SendTranscodeStatus(callbackURL, clients.TranscodeStatusTranscoding, 1)
time.Sleep(5 * time.Second)
callbackClient.SendTranscodeStatusCompleted(
callbackURL,
clients.InputVideo{
Format: "mp4",
Duration: 1234.5678,
Tracks: []clients.InputTrack{
{
Type: "video",
Codec: "h264",
DurationSec: 1.6,
Bitrate: 358315,
VideoTrack: clients.VideoTrack{
FPS: 30,
Width: 1920,
Height: 1080,
PixelFormat: "yuv420p",
},
},
{
Type: "audio",
Codec: "aac",
Bitrate: 141341,
DurationSec: 1.599979,
AudioTrack: clients.AudioTrack{
Channels: 2,
SampleRate: 48000,
},
},
},
},
[]clients.OutputVideo{
{
Type: "google-s3",
Manifest: "s3://livepeer-studio-uploads/videos/<video-id>/master.m3u8",
Videos: []clients.OutputVideoFile{
{
Type: "mp4",
SizeBytes: 12345,
Location: "s3://livepeer-studio-uploads/videos/<video-id>/video-480p.mp4",
},
},
},
},
)
}

0 comments on commit f8d600f

Please sign in to comment.