Use the highest quality video segment to creat thumbnails from. Closes
This commit is contained in:
parent
9357192947
commit
1133edf716
@ -5,10 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/gabek/owncast/utils"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/gabek/owncast/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//Config contains a reference to the configuration
|
//Config contains a reference to the configuration
|
||||||
@ -49,6 +48,7 @@ type videoSettings struct {
|
|||||||
StreamingKey string `yaml:"streamingKey"`
|
StreamingKey string `yaml:"streamingKey"`
|
||||||
StreamQualities []StreamQuality `yaml:"streamQualities"`
|
StreamQualities []StreamQuality `yaml:"streamQualities"`
|
||||||
OfflineContent string `yaml:"offlineContent"`
|
OfflineContent string `yaml:"offlineContent"`
|
||||||
|
HighestQualityStreamIndex int `yaml"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// StreamQuality defines the specifics of a single HLS stream variant.
|
// StreamQuality defines the specifics of a single HLS stream variant.
|
||||||
@ -106,6 +106,8 @@ func (c *config) load(filePath string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.VideoSettings.HighestQualityStreamIndex = findHighestQuality(c.VideoSettings.StreamQualities)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
config/configUtils.go
Normal file
34
config/configUtils.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import "sort"
|
||||||
|
|
||||||
|
func findHighestQuality(qualities []StreamQuality) int {
|
||||||
|
type IndexedQuality struct {
|
||||||
|
index int
|
||||||
|
quality StreamQuality
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(qualities) < 2 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
indexedQualities := make([]IndexedQuality, 0)
|
||||||
|
for index, quality := range qualities {
|
||||||
|
indexedQuality := IndexedQuality{index, quality}
|
||||||
|
indexedQualities = append(indexedQualities, indexedQuality)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(indexedQualities, func(a, b int) bool {
|
||||||
|
if indexedQualities[a].quality.IsVideoPassthrough && !indexedQualities[b].quality.IsVideoPassthrough {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !indexedQualities[a].quality.IsVideoPassthrough && indexedQualities[b].quality.IsVideoPassthrough {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return indexedQualities[a].quality.VideoBitrate > indexedQualities[b].quality.VideoBitrate
|
||||||
|
})
|
||||||
|
|
||||||
|
return indexedQualities[0].index
|
||||||
|
}
|
@ -4,6 +4,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//StartThumbnailGenerator starts generating thumbnails
|
//StartThumbnailGenerator starts generating thumbnails
|
||||||
func StartThumbnailGenerator(chunkPath string) {
|
func StartThumbnailGenerator(chunkPath string, variantIndex int) {
|
||||||
// Every 20 seconds create a thumbnail from the most
|
// Every 20 seconds create a thumbnail from the most
|
||||||
// recent video segment.
|
// recent video segment.
|
||||||
ticker := time.NewTicker(20 * time.Second)
|
ticker := time.NewTicker(20 * time.Second)
|
||||||
@ -23,7 +24,7 @@ func StartThumbnailGenerator(chunkPath string) {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
if err := fireThumbnailGenerator(chunkPath); err != nil {
|
if err := fireThumbnailGenerator(chunkPath, variantIndex); err != nil {
|
||||||
log.Errorln("Unable to generate thumbnail:", err)
|
log.Errorln("Unable to generate thumbnail:", err)
|
||||||
}
|
}
|
||||||
case <-quit:
|
case <-quit:
|
||||||
@ -36,11 +37,11 @@ func StartThumbnailGenerator(chunkPath string) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func fireThumbnailGenerator(chunkPath string) error {
|
func fireThumbnailGenerator(chunkPath string, variantIndex int) error {
|
||||||
// JPG takes less time to encode than PNG
|
// JPG takes less time to encode than PNG
|
||||||
outputFile := path.Join("webroot", "thumbnail.jpg")
|
outputFile := path.Join("webroot", "thumbnail.jpg")
|
||||||
|
|
||||||
framePath := path.Join(chunkPath, "0")
|
framePath := path.Join(chunkPath, strconv.Itoa(variantIndex))
|
||||||
files, err := ioutil.ReadDir(framePath)
|
files, err := ioutil.ReadDir(framePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -39,7 +39,7 @@ func SetStreamAsConnected() {
|
|||||||
chunkPath = config.Config.PrivateHLSPath
|
chunkPath = config.Config.PrivateHLSPath
|
||||||
}
|
}
|
||||||
|
|
||||||
ffmpeg.StartThumbnailGenerator(chunkPath)
|
ffmpeg.StartThumbnailGenerator(chunkPath, config.Config.VideoSettings.HighestQualityStreamIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
//SetStreamAsDisconnected sets the stream as disconnected
|
//SetStreamAsDisconnected sets the stream as disconnected
|
||||||
|
Loading…
x
Reference in New Issue
Block a user