Generate a static thumbnail png every 20s

This commit is contained in:
Gabe Kangas 2020-06-10 01:16:17 -07:00
parent 33278fc2c5
commit 9ebec675b5
3 changed files with 80 additions and 4 deletions

View file

@ -13,14 +13,13 @@ var configuration = getConfig()
var server *Server var server *Server
var online = false var online = false
var usingExternalStorage = false
func main() { func main() {
log.Println("Starting up. Please wait...") log.Println("Starting up. Please wait...")
resetDirectories(configuration) resetDirectories(configuration)
checkConfig(configuration) checkConfig(configuration)
var usingExternalStorage = false
if configuration.IPFS.Enabled { if configuration.IPFS.Enabled {
storage = &IPFSStorage{} storage = &IPFSStorage{}
usingExternalStorage = true usingExternalStorage = true
@ -66,6 +65,11 @@ func getStatus(w http.ResponseWriter, r *http.Request) {
func streamConnected() { func streamConnected() {
online = true online = true
chunkPath := configuration.PublicHLSPath
if usingExternalStorage {
chunkPath = configuration.PrivateHLSPath
}
startThumbnailGenerator(chunkPath)
} }
func streamDisconnected() { func streamDisconnected() {

72
thumbnailGenerator.go Normal file
View file

@ -0,0 +1,72 @@
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"time"
)
func startThumbnailGenerator(chunkPath string) {
// Every 20 seconds create a thumbnail from the most
// recent video segment.
ticker := time.NewTicker(20 * time.Second)
quit := make(chan struct{})
go func() {
for {
select {
case <-ticker.C:
fireThumbnailGenerator(chunkPath)
case <-quit:
ticker.Stop()
return
}
}
}()
}
func fireThumbnailGenerator(chunkPath string) {
framePath := path.Join(chunkPath, "0")
files, err := ioutil.ReadDir(framePath)
outputFile := path.Join("webroot", "thumbnail.png")
// fmt.Println("Generating thumbnail from", framePath, "to", outputFile)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
var modTime time.Time
var names []string
for _, fi := range files {
if path.Ext(fi.Name()) != ".ts" {
continue
}
if fi.Mode().IsRegular() {
if !fi.ModTime().Before(modTime) {
if fi.ModTime().After(modTime) {
modTime = fi.ModTime()
names = names[:0]
}
names = append(names, fi.Name())
}
}
}
if len(names) == 0 {
return
}
mostRecentFile := path.Join(framePath, names[0])
ffmpegCmd := "ffmpeg -y -i " + mostRecentFile + " -ss 00:00:01.000 -vframes 1 " + outputFile
// fmt.Println(ffmpegCmd)
_, err = exec.Command("sh", "-c", ffmpegCmd).Output()
verifyError(err)
}

View file

@ -31,10 +31,10 @@
id="video" id="video"
class="video-js vjs-theme-fantasy" class="video-js vjs-theme-fantasy"
preload="auto" preload="auto"
poster="https://picsum.photos/900/600" poster="/thumbnail.png"
autoplay autoplay
controls controls
style="width: 100%;" style="width: 100%; height: 600px;"
data-setup='{}' data-setup='{}'
> >
<source src="hls/stream.m3u8" type="application/x-mpegURL"/> <source src="hls/stream.m3u8" type="application/x-mpegURL"/>