mirror of
https://github.com/owncast/owncast.git
synced 2024-11-29 03:29:03 +03:00
5214d81264
* Query for installed codecs * Start modeling out codecs * Can now specify a codec and get the correct settings returned from the model * Return codecs in admin/serverconfig * Start handling transcoding errors and return messages to user * filter available codecs against a whitelist * Fix merge * Codecs are working * Switching between codecs work * Add apis for setting a custom video codec * Cleanup the logging of transcoder errors * Add v4l codec * Add fetching v4l * Add support for per-codec presets * Use updated nvenc encoding parameters * Update log message * Some more codec WIP * Turn off v4l. It is a mess. * Try to make the lowest latency level a bit more playable * Use a human redable display name in console messages * Turn on transcoder persistent connections * Add more codec-related user-facing error messages * Give the initial offline state transcoder an id * Force a minimum segment count of 3 * Disable qsv for now. set x264 specific params in VariantFlags * Close body in case * Ignore vbv underflow message, it is not actionable * Determine a dynamic gop value based on the length of segments * Add codec-specific tests * Cleanup * Ignore goconst lint warnings in codec file * Troubleshoot omx * Add more codec tests * Remove no longer accurate comment * Bundle admin from codec branch * Revert back to old setting * Cleanup list of codecs a bit * Remove old references to the encoder preset * Commit updated API documentation * Update admin bundle * Commit updated API documentation * Add codec setting to api spec * Commit updated API documentation Co-authored-by: Owncast <owncast@owncast.online>
106 lines
2.9 KiB
Go
106 lines
2.9 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math"
|
|
)
|
|
|
|
// StreamOutputVariant defines the output specifics of a single HLS stream variant.
|
|
type StreamOutputVariant struct {
|
|
// Name is an optional human-readable label for this stream output.
|
|
Name string `json:"name"`
|
|
|
|
// Enable passthrough to copy the video and/or audio directly from the
|
|
// incoming stream and disable any transcoding. It will ignore any of
|
|
// the below settings.
|
|
IsVideoPassthrough bool `yaml:"videoPassthrough" json:"videoPassthrough"`
|
|
IsAudioPassthrough bool `yaml:"audioPassthrough" json:"audioPassthrough"`
|
|
|
|
VideoBitrate int `yaml:"videoBitrate" json:"videoBitrate"`
|
|
AudioBitrate int `yaml:"audioBitrate" json:"audioBitrate"`
|
|
|
|
// Set only one of these in order to keep your current aspect ratio.
|
|
// Or set neither to not scale the video.
|
|
ScaledWidth int `yaml:"scaledWidth" json:"scaledWidth,omitempty"`
|
|
ScaledHeight int `yaml:"scaledHeight" json:"scaledHeight,omitempty"`
|
|
|
|
Framerate int `yaml:"framerate" json:"framerate"`
|
|
// CPUUsageLevel represents a codec preset to configure CPU usage.
|
|
CPUUsageLevel int `json:"cpuUsageLevel"`
|
|
}
|
|
|
|
// GetFramerate returns the framerate or default.
|
|
func (q *StreamOutputVariant) GetFramerate() int {
|
|
if q.IsVideoPassthrough {
|
|
return 0
|
|
}
|
|
|
|
if q.Framerate > 0 {
|
|
return q.Framerate
|
|
}
|
|
|
|
return 24
|
|
}
|
|
|
|
// GetIsAudioPassthrough will return if this variant audio is passthrough.
|
|
func (q *StreamOutputVariant) GetIsAudioPassthrough() bool {
|
|
if q.IsAudioPassthrough {
|
|
return true
|
|
}
|
|
|
|
if q.AudioBitrate == 0 {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// GetName will return the human readable name for this stream output.
|
|
func (q *StreamOutputVariant) GetName() string {
|
|
bitrate := getBitrateString(q.VideoBitrate)
|
|
|
|
if q.Name != "" {
|
|
return q.Name
|
|
} else if q.IsVideoPassthrough {
|
|
return "Source"
|
|
} else if q.ScaledHeight == 720 && q.ScaledWidth == 1080 {
|
|
return fmt.Sprintf("720p @%s", bitrate)
|
|
} else if q.ScaledHeight == 1080 && q.ScaledWidth == 1920 {
|
|
return fmt.Sprintf("1080p @%s", bitrate)
|
|
} else if q.ScaledHeight != 0 {
|
|
return fmt.Sprintf("%dh", q.ScaledHeight)
|
|
} else if q.ScaledWidth != 0 {
|
|
return fmt.Sprintf("%dw", q.ScaledWidth)
|
|
} else {
|
|
return fmt.Sprintf("%s@%dfps", bitrate, q.Framerate)
|
|
}
|
|
}
|
|
|
|
func getBitrateString(bitrate int) string {
|
|
if bitrate == 0 {
|
|
return ""
|
|
} else if bitrate < 1000 {
|
|
return fmt.Sprintf("%dKbps", bitrate)
|
|
} else if bitrate >= 1000 {
|
|
if math.Mod(float64(bitrate), 1000) == 0 {
|
|
return fmt.Sprintf("%dMbps", bitrate/1000.0)
|
|
} else {
|
|
return fmt.Sprintf("%.1fMbps", float32(bitrate)/1000.0)
|
|
}
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// MarshalJSON is a custom JSON marshal function for video stream qualities.
|
|
func (q *StreamOutputVariant) MarshalJSON() ([]byte, error) {
|
|
type Alias StreamOutputVariant
|
|
return json.Marshal(&struct {
|
|
Framerate int `json:"framerate"`
|
|
*Alias
|
|
}{
|
|
Framerate: q.GetFramerate(),
|
|
Alias: (*Alias)(q),
|
|
})
|
|
}
|