Enable passthrough video, where there is no reencoding and is lighterweight
This commit is contained in:
parent
6439075f36
commit
d53fe98543
@ -25,6 +25,7 @@ type VideoSettings struct {
|
|||||||
StreamingKey string `yaml:"streamingKey"`
|
StreamingKey string `yaml:"streamingKey"`
|
||||||
EncoderPreset string `yaml:"encoderPreset"`
|
EncoderPreset string `yaml:"encoderPreset"`
|
||||||
StreamQualities []StreamQuality `yaml:"streamQualities"`
|
StreamQualities []StreamQuality `yaml:"streamQualities"`
|
||||||
|
EnablePassthrough bool `yaml:"passthrough"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type StreamQuality struct {
|
type StreamQuality struct {
|
||||||
@ -106,7 +107,4 @@ func checkConfig(config Config) {
|
|||||||
panic("A video encoder preset is required to be set in the config file.")
|
panic("A video encoder preset is required to be set in the config file.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(config.VideoSettings.StreamQualities) < 1 {
|
|
||||||
panic("At least one stream quality must be set in the config file.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ videoSettings:
|
|||||||
chunkLengthInSeconds: 4
|
chunkLengthInSeconds: 4
|
||||||
streamingKey: abc123
|
streamingKey: abc123
|
||||||
encoderPreset: superfast # https://trac.ffmpeg.org/wiki/Encode/H.264
|
encoderPreset: superfast # https://trac.ffmpeg.org/wiki/Encode/H.264
|
||||||
|
passthrough: true # Enabling this will ignore the below stream qualities and pass through the same quality that you're sending it
|
||||||
|
|
||||||
streamQualities:
|
streamQualities:
|
||||||
- bitrate: 6000k
|
- bitrate: 6000k
|
||||||
|
29
ffmpeg.go
29
ffmpeg.go
@ -33,21 +33,33 @@ func startFfmpeg(configuration Config) {
|
|||||||
var videoMaps = make([]string, 0)
|
var videoMaps = make([]string, 0)
|
||||||
var streamMaps = make([]string, 0)
|
var streamMaps = make([]string, 0)
|
||||||
var audioMaps = make([]string, 0)
|
var audioMaps = make([]string, 0)
|
||||||
for index, quality := range configuration.VideoSettings.StreamQualities {
|
var videoMapsString = ""
|
||||||
videoMaps = append(videoMaps, fmt.Sprintf("-map v:0 -c:v:%d libx264 -b:v:%d %s", index, index, quality.Bitrate))
|
var audioMapsString = ""
|
||||||
streamMaps = append(streamMaps, fmt.Sprintf("v:%d,a:%d", index, index))
|
var streamMappingString = ""
|
||||||
audioMaps = append(audioMaps, "-map a:0")
|
|
||||||
|
if configuration.VideoSettings.EnablePassthrough || len(configuration.VideoSettings.StreamQualities) == 0 {
|
||||||
|
fmt.Println("Enabling passthrough video")
|
||||||
|
// videoMaps = append(videoMaps, fmt.Sprintf("-map 0:v -c:v copy"))
|
||||||
|
streamMaps = append(streamMaps, fmt.Sprintf("v:%d,a:%d", 0, 0))
|
||||||
|
} else {
|
||||||
|
for index, quality := range configuration.VideoSettings.StreamQualities {
|
||||||
|
videoMaps = append(videoMaps, fmt.Sprintf("-map v:0 -c:v:%d libx264 -b:v:%d %s", index, index, quality.Bitrate))
|
||||||
|
streamMaps = append(streamMaps, fmt.Sprintf("v:%d,a:%d", index, index))
|
||||||
|
videoMapsString = strings.Join(videoMaps, " ")
|
||||||
|
audioMaps = append(audioMaps, "-map a:0")
|
||||||
|
audioMapsString = strings.Join(audioMaps, " ") + " -c:a copy" // Pass through audio for all the variants, don't reencode
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
streamMappingString = "-var_stream_map \"" + strings.Join(streamMaps, " ") + "\""
|
||||||
ffmpegFlags := []string{
|
ffmpegFlags := []string{
|
||||||
"-hide_banner",
|
"-hide_banner",
|
||||||
"-re",
|
"-re",
|
||||||
"-i pipe:",
|
"-i pipe:",
|
||||||
// "-vf scale=900:-2", // Re-enable in the future with a config to togging resizing?
|
// "-vf scale=900:-2", // Re-enable in the future with a config to togging resizing?
|
||||||
// "-sws_flags fast_bilinear",
|
// "-sws_flags fast_bilinear",
|
||||||
strings.Join(videoMaps, " "), // All the different video variants
|
videoMapsString, // All the different video variants
|
||||||
strings.Join(audioMaps, " ") + " -c:a copy", // Audio for all the variants
|
audioMapsString,
|
||||||
// strings.Join(audioMaps, " ") + " -c:a aac -b:a 192k -ac 2", // Audio for all the variants
|
|
||||||
"-master_pl_name stream.m3u8",
|
"-master_pl_name stream.m3u8",
|
||||||
"-g 60", "-keyint_min 60", // create key frame (I-frame) every 48 frames (~2 seconds) - will later affect correct slicing of segments and alignment of renditions
|
"-g 60", "-keyint_min 60", // create key frame (I-frame) every 48 frames (~2 seconds) - will later affect correct slicing of segments and alignment of renditions
|
||||||
"-framerate 30",
|
"-framerate 30",
|
||||||
@ -66,8 +78,7 @@ func startFfmpeg(configuration Config) {
|
|||||||
"-segment_wrap 100",
|
"-segment_wrap 100",
|
||||||
"-tune zerolatency",
|
"-tune zerolatency",
|
||||||
|
|
||||||
// "-master_m3u8_publish_rate 5",
|
streamMappingString,
|
||||||
"-var_stream_map \"" + strings.Join(streamMaps, " ") + "\"",
|
|
||||||
variantPlaylistName,
|
variantPlaylistName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,13 +53,16 @@ func getVariantIndexFromPath(fullDiskPath string) int {
|
|||||||
var variants []Variant
|
var variants []Variant
|
||||||
|
|
||||||
func monitorVideoContent(pathToMonitor string, configuration Config, storage ChunkStorage) {
|
func monitorVideoContent(pathToMonitor string, configuration Config, storage ChunkStorage) {
|
||||||
// Create structures to store the segments for the different stream variants
|
// Create at least one structure to store the segments for the different stream variants
|
||||||
variants = make([]Variant, len(configuration.VideoSettings.StreamQualities))
|
variants = make([]Variant, len(configuration.VideoSettings.StreamQualities))
|
||||||
for index := range variants {
|
if len(configuration.VideoSettings.StreamQualities) > 0 && !configuration.VideoSettings.EnablePassthrough {
|
||||||
variants[index] = Variant{index, make([]Segment, 0)}
|
for index := range variants {
|
||||||
|
variants[index] = Variant{index, make([]Segment, 0)}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
variants[0] = Variant{0, make([]Segment, 0)}
|
||||||
}
|
}
|
||||||
|
log.Printf("Using directory %s for storing files with %d variants...\n", pathToMonitor, len(variants))
|
||||||
log.Printf("Using %s for storing files with %d variants...\n", pathToMonitor, len(variants))
|
|
||||||
|
|
||||||
w := watcher.New()
|
w := watcher.New()
|
||||||
|
|
||||||
|
14
utils.go
14
utils.go
@ -57,13 +57,19 @@ func copy(src, dst string) {
|
|||||||
func resetDirectories(configuration Config) {
|
func resetDirectories(configuration Config) {
|
||||||
// Wipe the public, web-accessible hls data directory
|
// Wipe the public, web-accessible hls data directory
|
||||||
os.RemoveAll(configuration.PublicHLSPath)
|
os.RemoveAll(configuration.PublicHLSPath)
|
||||||
|
os.RemoveAll(configuration.PrivateHLSPath)
|
||||||
os.MkdirAll(configuration.PublicHLSPath, 0777)
|
os.MkdirAll(configuration.PublicHLSPath, 0777)
|
||||||
|
os.MkdirAll(configuration.PrivateHLSPath, 0777)
|
||||||
|
|
||||||
// Create private hls data dirs
|
// Create private hls data dirs
|
||||||
os.RemoveAll(configuration.PrivateHLSPath)
|
if !configuration.VideoSettings.EnablePassthrough || len(configuration.VideoSettings.StreamQualities) == 0 {
|
||||||
for index := range configuration.VideoSettings.StreamQualities {
|
for index := range configuration.VideoSettings.StreamQualities {
|
||||||
os.MkdirAll(path.Join(configuration.PrivateHLSPath, strconv.Itoa(index)), 0777)
|
os.MkdirAll(path.Join(configuration.PrivateHLSPath, strconv.Itoa(index)), 0777)
|
||||||
os.MkdirAll(path.Join(configuration.PublicHLSPath, strconv.Itoa(index)), 0777)
|
os.MkdirAll(path.Join(configuration.PublicHLSPath, strconv.Itoa(index)), 0777)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
os.MkdirAll(path.Join(configuration.PrivateHLSPath, strconv.Itoa(0)), 0777)
|
||||||
|
os.MkdirAll(path.Join(configuration.PublicHLSPath, strconv.Itoa(0)), 0777)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user