-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvsize.go
79 lines (68 loc) · 1.49 KB
/
vsize.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package main
import (
"fmt"
)
type vsize struct {
w, h int
}
func (v *vsize) String() string {
return fmt.Sprintf("%dx%d", v.w, v.h)
}
func (v *vsize) Scale() string {
return fmt.Sprintf("scale=w=%d:h=%d", v.w, v.h)
}
// isOver returns true if width or height is over the provided value
func (v *vsize) isOver(n int) bool {
return v.w > n || v.h > n
}
func (v *vsize) smaller() *vsize {
if v.w < v.h {
// reverse it, make it smaller, reverse it again
return v.reverse().smaller().reverse()
}
steps := []int{4320, 2160, 1440, 1080, 720, 480, 360, 240} //, 144}
for _, nh := range steps {
// skip if height is more than current
if v.h <= nh {
continue
}
// resize to 1920x1080
if v.w*nh%v.h != 0 {
continue
}
nw := v.w * nh / v.h
if nw&1 != 0 {
nw -= 1
}
if nw <= 145 || nh <= 145 {
// too small
return nil
}
return &vsize{w: nw, h: nh}
}
return nil
}
func (v *vsize) reverse() *vsize {
if v == nil {
return nil
}
return &vsize{w: v.h, h: v.w}
}
func (v *vsize) bitrate(framerate, bitsPerPixel float64) uint64 {
// compute ideal bitrate for h264: 0.1 bit per pixel
// 1080p@60fps is ~6Mbps
return uint64(float64(v.w) * float64(v.h) * framerate * bitsPerPixel)
}
func (v *vsize) variants() []*hlsVariant {
// make a smart variant depending on the size
if v.isOver(1280) {
return []*hlsVariant{
&hlsVariant{size: v, codec: AV1},
&hlsVariant{size: v, codec: HEVC},
}
} else {
return []*hlsVariant{
&hlsVariant{size: v, codec: H264},
}
}
}