Tuning
parent
91c6a43fc1
commit
75d2768fe6
|
@ -3,5 +3,5 @@ package main
|
|||
type Config struct {
|
||||
ffmpeg string
|
||||
ffprobe string
|
||||
chunkSize float64
|
||||
chunkSize int
|
||||
}
|
||||
|
|
2
main.go
2
main.go
|
@ -111,7 +111,7 @@ func main() {
|
|||
h := NewHandler(&Config{
|
||||
ffmpeg: "ffmpeg",
|
||||
ffprobe: "ffprobe",
|
||||
chunkSize: 2.0,
|
||||
chunkSize: 3,
|
||||
})
|
||||
|
||||
http.Handle("/", h)
|
||||
|
|
14
manager.go
14
manager.go
|
@ -42,15 +42,15 @@ func NewManager(c *Config, path string, id string, close chan string) (*Manager,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
m.numChunks = int(math.Ceil(m.probe.Duration.Seconds() / c.chunkSize))
|
||||
m.numChunks = int(math.Ceil(m.probe.Duration.Seconds() / float64(c.chunkSize)))
|
||||
|
||||
// Possible streams
|
||||
m.streams["360p"] = &Stream{c: c, m: m, quality: "360p", height: 360, width: 640, bitrate: 945000}
|
||||
m.streams["480p"] = &Stream{c: c, m: m, quality: "480p", height: 480, width: 640, bitrate: 1365000}
|
||||
m.streams["720p"] = &Stream{c: c, m: m, quality: "720p", height: 720, width: 1280, bitrate: 3045000}
|
||||
m.streams["1080p"] = &Stream{c: c, m: m, quality: "1080p", height: 1080, width: 1920, bitrate: 6045000}
|
||||
m.streams["1440p"] = &Stream{c: c, m: m, quality: "1440p", height: 1440, width: 2560, bitrate: 9045000}
|
||||
m.streams["2160p"] = &Stream{c: c, m: m, quality: "2160p", height: 2160, width: 3840, bitrate: 14045000}
|
||||
m.streams["360p"] = &Stream{c: c, m: m, quality: "360p", height: 360, width: 640, bitrate: 800000}
|
||||
m.streams["480p"] = &Stream{c: c, m: m, quality: "480p", height: 480, width: 640, bitrate: 1500000}
|
||||
m.streams["720p"] = &Stream{c: c, m: m, quality: "720p", height: 720, width: 1280, bitrate: 3000000}
|
||||
m.streams["1080p"] = &Stream{c: c, m: m, quality: "1080p", height: 1080, width: 1920, bitrate: 5000000}
|
||||
m.streams["1440p"] = &Stream{c: c, m: m, quality: "1440p", height: 1440, width: 2560, bitrate: 9000000}
|
||||
m.streams["2160p"] = &Stream{c: c, m: m, quality: "2160p", height: 2160, width: 3840, bitrate: 14000000}
|
||||
|
||||
// Only keep streams that are smaller than the video
|
||||
for k, stream := range m.streams {
|
||||
|
|
24
stream.go
24
stream.go
|
@ -51,12 +51,12 @@ func (s *Stream) ServeList(w http.ResponseWriter) error {
|
|||
w.Write([]byte("#EXT-X-VERSION:4\n"))
|
||||
w.Write([]byte("#EXT-X-MEDIA-SEQUENCE:0\n"))
|
||||
w.Write([]byte("#EXT-X-PLAYLIST-TYPE:VOD\n"))
|
||||
w.Write([]byte(fmt.Sprintf("#EXT-X-TARGETDURATION:%.3f\n", s.c.chunkSize)))
|
||||
w.Write([]byte(fmt.Sprintf("#EXT-X-TARGETDURATION:%d\n", s.c.chunkSize)))
|
||||
|
||||
duration := s.m.probe.Duration.Seconds()
|
||||
i := 0
|
||||
for duration > 0 {
|
||||
size := s.c.chunkSize
|
||||
size := float64(s.c.chunkSize)
|
||||
if duration < size {
|
||||
size = duration
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ func (s *Stream) ServeList(w http.ResponseWriter) error {
|
|||
w.Write([]byte(fmt.Sprintf("#EXTINF:%.3f, nodesc\n", size)))
|
||||
w.Write([]byte(fmt.Sprintf("%s-%06d.ts\n", s.quality, i)))
|
||||
|
||||
duration -= s.c.chunkSize
|
||||
duration -= float64(s.c.chunkSize)
|
||||
i++
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ func (s *Stream) restartAtChunk(w http.ResponseWriter, id int) {
|
|||
}
|
||||
|
||||
func (s *Stream) transcode(startId int) {
|
||||
startAt := float64(startId) * s.c.chunkSize
|
||||
startAt := float64(startId * s.c.chunkSize)
|
||||
|
||||
args := []string{
|
||||
"-loglevel", "warning",
|
||||
|
@ -238,13 +238,14 @@ func (s *Stream) transcode(startId int) {
|
|||
"-vf", scale,
|
||||
"-c:v", CV,
|
||||
"-profile:v", "high",
|
||||
"-b:v", fmt.Sprintf("%dk", s.bitrate/1000),
|
||||
"-maxrate", fmt.Sprintf("%dk", s.bitrate/1000),
|
||||
"-bufsize", fmt.Sprintf("%dK", s.bitrate/3000),
|
||||
}...)
|
||||
|
||||
// Extra args only for x264
|
||||
if !VAAPI {
|
||||
args = append(args, []string{
|
||||
"-preset", "faster",
|
||||
"-preset", "fast",
|
||||
"-level:v", "4.0",
|
||||
}...)
|
||||
}
|
||||
|
@ -258,11 +259,9 @@ func (s *Stream) transcode(startId int) {
|
|||
// Segmenting specs
|
||||
args = append(args, []string{
|
||||
"-avoid_negative_ts", "disabled",
|
||||
"-max_muxing_queue_size", "2048",
|
||||
"-f", "hls",
|
||||
"-max_delay", "5000000",
|
||||
"-hls_time", fmt.Sprintf("%.6f", s.c.chunkSize),
|
||||
"-g", fmt.Sprintf("%.6f", s.c.chunkSize),
|
||||
"-hls_time", fmt.Sprintf("%d", s.c.chunkSize),
|
||||
"-g", fmt.Sprintf("%d", s.c.chunkSize),
|
||||
"-hls_segment_type", "mpegts",
|
||||
"-start_number", fmt.Sprintf("%d", startId),
|
||||
"-hls_segment_filename", s.getTsPath(-1),
|
||||
|
@ -270,7 +269,7 @@ func (s *Stream) transcode(startId int) {
|
|||
}...)
|
||||
|
||||
s.coder = exec.Command(s.c.ffmpeg, args...)
|
||||
// log.Println("Starting FFmpeg process with args", strings.Join(s.coder.Args[:], " "))
|
||||
log.Println("Starting FFmpeg process with args", strings.Join(s.coder.Args[:], " "))
|
||||
|
||||
cmdStdOut, err := s.coder.StdoutPipe()
|
||||
if err != nil {
|
||||
|
@ -358,6 +357,9 @@ func (s *Stream) monitorTranscodeOutput(cmdStdOut io.ReadCloser, startAt float64
|
|||
|
||||
// Notify everyone
|
||||
chunk := s.createChunk(id)
|
||||
if chunk.done {
|
||||
return
|
||||
}
|
||||
chunk.done = true
|
||||
for _, n := range chunk.notifs {
|
||||
n <- true
|
||||
|
|
Loading…
Reference in New Issue