Browse Source

Use the highest quality video segment to creat thumbnails from. Closes

pull/53/head
Gabe Kangas 5 years ago
parent
commit
1133edf716
  1. 14
      config/config.go
  2. 34
      config/configUtils.go
  3. 9
      core/ffmpeg/thumbnailGenerator.go
  4. 2
      core/status.go

14
config/config.go

@ -5,10 +5,9 @@ import ( @@ -5,10 +5,9 @@ import (
"fmt"
"io/ioutil"
"github.com/gabek/owncast/utils"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"github.com/gabek/owncast/utils"
)
//Config contains a reference to the configuration
@ -45,10 +44,11 @@ type socialHandle struct { @@ -45,10 +44,11 @@ type socialHandle struct {
}
type videoSettings struct {
ChunkLengthInSeconds int `yaml:"chunkLengthInSeconds"`
StreamingKey string `yaml:"streamingKey"`
StreamQualities []StreamQuality `yaml:"streamQualities"`
OfflineContent string `yaml:"offlineContent"`
ChunkLengthInSeconds int `yaml:"chunkLengthInSeconds"`
StreamingKey string `yaml:"streamingKey"`
StreamQualities []StreamQuality `yaml:"streamQualities"`
OfflineContent string `yaml:"offlineContent"`
HighestQualityStreamIndex int `yaml"-"`
}
// StreamQuality defines the specifics of a single HLS stream variant.
@ -106,6 +106,8 @@ func (c *config) load(filePath string) error { @@ -106,6 +106,8 @@ func (c *config) load(filePath string) error {
return err
}
c.VideoSettings.HighestQualityStreamIndex = findHighestQuality(c.VideoSettings.StreamQualities)
return nil
}

34
config/configUtils.go

@ -0,0 +1,34 @@ @@ -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
}

9
core/ffmpeg/thumbnailGenerator.go

@ -4,6 +4,7 @@ import ( @@ -4,6 +4,7 @@ import (
"io/ioutil"
"os/exec"
"path"
"strconv"
"strings"
"time"
@ -13,7 +14,7 @@ import ( @@ -13,7 +14,7 @@ import (
)
//StartThumbnailGenerator starts generating thumbnails
func StartThumbnailGenerator(chunkPath string) {
func StartThumbnailGenerator(chunkPath string, variantIndex int) {
// Every 20 seconds create a thumbnail from the most
// recent video segment.
ticker := time.NewTicker(20 * time.Second)
@ -23,7 +24,7 @@ func StartThumbnailGenerator(chunkPath string) { @@ -23,7 +24,7 @@ func StartThumbnailGenerator(chunkPath string) {
for {
select {
case <-ticker.C:
if err := fireThumbnailGenerator(chunkPath); err != nil {
if err := fireThumbnailGenerator(chunkPath, variantIndex); err != nil {
log.Errorln("Unable to generate thumbnail:", err)
}
case <-quit:
@ -36,11 +37,11 @@ func StartThumbnailGenerator(chunkPath string) { @@ -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
outputFile := path.Join("webroot", "thumbnail.jpg")
framePath := path.Join(chunkPath, "0")
framePath := path.Join(chunkPath, strconv.Itoa(variantIndex))
files, err := ioutil.ReadDir(framePath)
if err != nil {
return err

2
core/status.go

@ -39,7 +39,7 @@ func SetStreamAsConnected() { @@ -39,7 +39,7 @@ func SetStreamAsConnected() {
chunkPath = config.Config.PrivateHLSPath
}
ffmpeg.StartThumbnailGenerator(chunkPath)
ffmpeg.StartThumbnailGenerator(chunkPath, config.Config.VideoSettings.HighestQualityStreamIndex)
}
//SetStreamAsDisconnected sets the stream as disconnected

Loading…
Cancel
Save