72 lines
2.3 KiB
Go
72 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Parses the duration of the video from the ffmpeg header.
|
|
func parseDurationBitrate(video *Video, data []string) {
|
|
videoData := ""
|
|
for _, line := range data {
|
|
line = strings.TrimSpace(line)
|
|
if strings.HasPrefix(line, "Duration: ") {
|
|
videoData = line
|
|
break
|
|
}
|
|
}
|
|
if videoData == "" {
|
|
panic("Could not find duration in ffmpeg header.")
|
|
}
|
|
// Duration
|
|
duration := strings.Split(strings.SplitN(strings.SplitN(videoData, ",", 2)[0], "Duration:", 2)[1], ":")
|
|
seconds, _ := strconv.ParseFloat(duration[len(duration)-1], 64)
|
|
minutes, _ := strconv.ParseFloat(duration[len(duration)-2], 64)
|
|
hours, _ := strconv.ParseFloat(duration[len(duration)-3], 64)
|
|
video.duration = seconds + minutes*60 + hours*3600
|
|
|
|
// Bitrate
|
|
bitrate := strings.SplitN(strings.TrimSpace(strings.SplitN(videoData, "bitrate:", 2)[1]), " ", 2)[0]
|
|
video.bitrate, _ = strconv.Atoi(bitrate)
|
|
}
|
|
|
|
func parseVideoData(video *Video, data []string) {
|
|
videoData := ""
|
|
// Get string containing video data.
|
|
for _, line := range data {
|
|
line = strings.TrimSpace(line)
|
|
if strings.HasPrefix(line, "Stream") && strings.Contains(line, "Video:") {
|
|
videoData = strings.TrimSpace(strings.SplitN(line, "Video:", 2)[1])
|
|
break
|
|
}
|
|
}
|
|
if videoData == "" {
|
|
panic("No video data found in ffmpeg header.")
|
|
}
|
|
// Video Codec
|
|
video.codec = strings.TrimSpace(strings.SplitN(videoData, " ", 2)[0])
|
|
// FPS
|
|
fpsstr := strings.SplitN(videoData, "fps", 2)[0]
|
|
fps, _ := strconv.Atoi(strings.TrimSpace(fpsstr[strings.LastIndex(fpsstr, ",")+1:]))
|
|
video.fps = float64(fps)
|
|
// Pixel Format
|
|
video.pix_fmt = strings.TrimSpace(strings.Split(videoData, ",")[1])
|
|
// Width and Height
|
|
r, _ := regexp.Compile("\\d+x\\d+")
|
|
wh := r.FindAllString(videoData, -1)
|
|
dims := strings.SplitN(wh[len(wh)-1], "x", 2)
|
|
width, _ := strconv.Atoi(dims[0])
|
|
height, _ := strconv.Atoi(dims[1])
|
|
video.width = width
|
|
video.height = height
|
|
}
|
|
|
|
// Parses the ffmpeg header.
|
|
// Code inspired by the imageio-ffmpeg project.
|
|
// GitHub: https://github.com/imageio/imageio-ffmpeg/blob/master/imageio_ffmpeg/_parsing.py#L113
|
|
func parseFFMPEGHeader(video *Video, header string) {
|
|
data := strings.Split(strings.ReplaceAll(header, "\r\n", "\n"), "\n")
|
|
parseDurationBitrate(video, data)
|
|
parseVideoData(video, data)
|
|
}
|