Add transcode handlers
This commit is contained in:
202
handlers.go
202
handlers.go
@@ -311,7 +311,6 @@ func getVideoFPS(path string) (float64, error) {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
// TODO: this produces a string like "num/denom", do the division
|
||||
parts := strings.Split(strings.TrimSpace(stdout.String()), "/")
|
||||
if len(parts) != 2 {
|
||||
fmt.Println("getVideoFPS split error:", err, stdout.String())
|
||||
@@ -371,10 +370,13 @@ type VideoMeta struct {
|
||||
height uint
|
||||
fps float64
|
||||
length float64
|
||||
size int64 // file size
|
||||
}
|
||||
|
||||
type AudioMeta struct {
|
||||
rate uint
|
||||
rate uint
|
||||
length float64
|
||||
size int64 // file size
|
||||
}
|
||||
|
||||
func getVideoMeta(path string) (VideoMeta, error) {
|
||||
@@ -394,11 +396,16 @@ func getVideoMeta(path string) (VideoMeta, error) {
|
||||
if err != nil {
|
||||
return VideoMeta{}, err
|
||||
}
|
||||
size, err := getSize(path)
|
||||
if err != nil {
|
||||
return VideoMeta{}, err
|
||||
}
|
||||
return VideoMeta{
|
||||
width: w,
|
||||
height: h,
|
||||
fps: fps,
|
||||
length: length,
|
||||
size: size,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -440,11 +447,47 @@ func getAudioMeta(path string) (AudioMeta, error) {
|
||||
if err != nil {
|
||||
return AudioMeta{}, err
|
||||
}
|
||||
length, err := getLength(path)
|
||||
if err != nil {
|
||||
return AudioMeta{}, err
|
||||
}
|
||||
size, err := getSize(path)
|
||||
if err != nil {
|
||||
return AudioMeta{}, err
|
||||
}
|
||||
return AudioMeta{
|
||||
rate: rate,
|
||||
rate: rate,
|
||||
length: length,
|
||||
size: size,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func addAudioTranscode(mediaId, originalId, bitrate uint, srcKind string) {
|
||||
t := Transcode{
|
||||
SrcID: mediaId,
|
||||
OriginalID: originalId,
|
||||
SrcKind: srcKind,
|
||||
DstKind: "audio",
|
||||
Rate: bitrate,
|
||||
TimeSubmit: time.Now(),
|
||||
Status: "pending",
|
||||
}
|
||||
db.Create(&t)
|
||||
}
|
||||
|
||||
func addVideoTranscode(videoId, originalId, targetHeight uint) {
|
||||
t := Transcode{
|
||||
SrcID: videoId,
|
||||
OriginalID: originalId,
|
||||
SrcKind: "video",
|
||||
DstKind: "video",
|
||||
Height: targetHeight,
|
||||
TimeSubmit: time.Now(),
|
||||
Status: "pending",
|
||||
}
|
||||
db.Create(&t)
|
||||
}
|
||||
|
||||
func processOriginal(originalID uint) {
|
||||
|
||||
// check if there is an original video
|
||||
@@ -469,54 +512,16 @@ func processOriginal(originalID uint) {
|
||||
fmt.Println("Skipping non-existant file for processOriginal")
|
||||
return
|
||||
}
|
||||
videoMeta, err := getVideoMeta(videoFilepath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println(videoMeta)
|
||||
db.Model(&Video{}).Where("id = ?", video.ID).Update("fps", videoMeta.fps)
|
||||
db.Model(&Video{}).Where("id = ?", video.ID).Update("width", videoMeta.width)
|
||||
db.Model(&Video{}).Where("id = ?", video.ID).Update("height", videoMeta.height)
|
||||
db.Model(&Video{}).Where("id = ?", video.ID).Updates(map[string]interface{}{
|
||||
"fps": videoMeta.fps,
|
||||
"width": videoMeta.width,
|
||||
"height": videoMeta.height,
|
||||
"length": videoMeta.length,
|
||||
})
|
||||
}
|
||||
|
||||
videoSize, err := getSize(videoFilepath)
|
||||
if err == nil {
|
||||
db.Model(&Video{}).Where("id = ?", video.ID).Update("size", videoSize)
|
||||
}
|
||||
|
||||
// create audio transcodes
|
||||
for _, bitrate := range []uint{64, 96, 128, 160, 192} {
|
||||
t := Transcode{
|
||||
SrcID: video.ID,
|
||||
OriginalID: originalID,
|
||||
SrcKind: "video",
|
||||
DstKind: "audio",
|
||||
Rate: bitrate,
|
||||
TimeSubmit: time.Now(),
|
||||
Status: "pending",
|
||||
}
|
||||
db.Create(&t)
|
||||
addAudioTranscode(video.ID, originalID, bitrate, "video")
|
||||
}
|
||||
|
||||
// create video transcodes
|
||||
for _, targetHeight := range []uint{144, 480, 720, 1080} {
|
||||
if targetHeight <= videoMeta.height {
|
||||
t := Transcode{
|
||||
SrcID: video.ID,
|
||||
OriginalID: originalID,
|
||||
SrcKind: "video",
|
||||
DstKind: "video",
|
||||
Height: targetHeight,
|
||||
TimeSubmit: time.Now(),
|
||||
Status: "pending",
|
||||
}
|
||||
db.Create(&t)
|
||||
if targetHeight <= video.Height {
|
||||
addVideoTranscode(video.ID, originalID, targetHeight)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,35 +533,14 @@ func processOriginal(originalID uint) {
|
||||
fmt.Println("Skipping non-existant audio file for processOriginal")
|
||||
return
|
||||
}
|
||||
audioMeta, err := getAudioMeta(audioFilepath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println(audioMeta)
|
||||
db.Model(&Audio{}).Where("id = ?", audio.ID).Update("bps", audioMeta.rate)
|
||||
}
|
||||
|
||||
size, err := getSize(audioFilepath)
|
||||
if err == nil {
|
||||
db.Model(&Audio{}).Where("id = ?", audio.ID).Update("size", size)
|
||||
}
|
||||
|
||||
// create audio transcodes
|
||||
for _, bitrate := range []uint{64, 96, 128, 160, 192} {
|
||||
t := Transcode{
|
||||
SrcID: audio.ID,
|
||||
OriginalID: originalID,
|
||||
SrcKind: "audio",
|
||||
DstKind: "audio",
|
||||
Rate: bitrate,
|
||||
TimeSubmit: time.Now(),
|
||||
Status: "pending",
|
||||
}
|
||||
db.Create(&t)
|
||||
addAudioTranscode(video.ID, originalID, bitrate, "audio")
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Errorf("No original video or audio for %d found in processOriginal", originalID)
|
||||
log.Errorf("No original video or audio for original %d found in processOriginal", originalID)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -610,17 +594,21 @@ func startDownload(originalID uint, videoURL string, audioOnly bool) {
|
||||
return
|
||||
}
|
||||
|
||||
length, _ := getLength(dlFilepath)
|
||||
size, _ := getSize(dlFilepath)
|
||||
|
||||
if audioOnly {
|
||||
mediaMeta, err := getAudioMeta(dlFilepath)
|
||||
if err != nil {
|
||||
log.Errorln("couldn't get audio file metadata", err)
|
||||
SetOriginalStatus(originalID, Failed)
|
||||
return
|
||||
}
|
||||
|
||||
audio := Audio{
|
||||
OriginalID: originalID,
|
||||
Filename: dlFilename,
|
||||
Source: "original",
|
||||
Type: origMeta.ext,
|
||||
Length: length,
|
||||
Size: size,
|
||||
Length: mediaMeta.length,
|
||||
Size: mediaMeta.size,
|
||||
}
|
||||
fmt.Println("create Audio", audio)
|
||||
if db.Create(&audio).Error != nil {
|
||||
@@ -629,17 +617,27 @@ func startDownload(originalID uint, videoURL string, audioOnly bool) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
mediaMeta, err := getVideoMeta(dlFilepath)
|
||||
if err != nil {
|
||||
log.Errorln("couldn't get video file metadata", err)
|
||||
SetOriginalStatus(originalID, Failed)
|
||||
return
|
||||
}
|
||||
|
||||
video := Video{
|
||||
OriginalID: originalID,
|
||||
Filename: dlFilename,
|
||||
Source: "original",
|
||||
Type: origMeta.ext,
|
||||
Length: length,
|
||||
Size: size,
|
||||
FPS: mediaMeta.fps,
|
||||
Width: mediaMeta.width,
|
||||
Height: mediaMeta.height,
|
||||
Length: mediaMeta.length,
|
||||
Size: mediaMeta.size,
|
||||
}
|
||||
fmt.Println("create Video", video)
|
||||
log.Debugln("create Video", video)
|
||||
if db.Create(&video).Error != nil {
|
||||
fmt.Println("Couldn't create video entry", err)
|
||||
log.Errorln("Couldn't create video entry", err)
|
||||
SetOriginalStatus(originalID, Failed)
|
||||
return
|
||||
}
|
||||
@@ -927,6 +925,58 @@ func deleteAudioHandler(c echo.Context) error {
|
||||
return c.Redirect(http.StatusSeeOther, referrer)
|
||||
}
|
||||
|
||||
func transcodeToVideoHandler(c echo.Context) error {
|
||||
originalId, _ := strconv.ParseUint(c.FormValue("original_id"), 10, 32)
|
||||
height, _ := strconv.ParseUint(c.FormValue("height"), 10, 32)
|
||||
referrer := c.Request().Referer()
|
||||
if referrer == "" {
|
||||
referrer = "/"
|
||||
}
|
||||
|
||||
var video Video
|
||||
err := db.Where("source = ?", "original").Where("original_id = ?", originalId).First(&video).Error
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
log.Errorf("no video record for original %d: %v", originalId, err)
|
||||
} else {
|
||||
addVideoTranscode(video.ID, uint(originalId), uint(height))
|
||||
}
|
||||
|
||||
return c.Redirect(http.StatusSeeOther, referrer)
|
||||
}
|
||||
|
||||
func transcodeToAudioHandler(c echo.Context) error {
|
||||
originalId, _ := strconv.ParseUint(c.FormValue("original_id"), 10, 32)
|
||||
kbps, _ := strconv.ParseUint(c.FormValue("kbps"), 10, 32)
|
||||
referrer := c.Request().Referer()
|
||||
if referrer == "" {
|
||||
referrer = "/"
|
||||
}
|
||||
|
||||
// check if there is an original video
|
||||
hasOriginalVideo := true
|
||||
hasOriginalAudio := true
|
||||
var video Video
|
||||
var audio Audio
|
||||
err := db.Where("source = ?", "original").Where("original_id = ?", originalId).First(&video).Error
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
hasOriginalVideo = false
|
||||
}
|
||||
err = db.Where("source = ?", "original").Where("original_id = ?", originalId).First(&audio).Error
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
hasOriginalAudio = false
|
||||
}
|
||||
|
||||
if hasOriginalVideo {
|
||||
addAudioTranscode(video.ID, uint(originalId), uint(kbps), "video")
|
||||
} else if hasOriginalAudio {
|
||||
addAudioTranscode(audio.ID, uint(originalId), uint(kbps), "audio")
|
||||
} else {
|
||||
log.Errorln("no audio or video record for original", originalId)
|
||||
}
|
||||
|
||||
return c.Redirect(http.StatusSeeOther, referrer)
|
||||
}
|
||||
|
||||
func tempHandler(c echo.Context) error {
|
||||
token := c.Param("token")
|
||||
|
||||
|
2
main.go
2
main.go
@@ -125,6 +125,8 @@ func main() {
|
||||
e.POST("/video/:id/process", processHandler, authMiddleware)
|
||||
e.POST("/delete_video/:id", deleteVideoHandler, authMiddleware)
|
||||
e.POST("/delete_audio/:id", deleteAudioHandler, authMiddleware)
|
||||
e.POST("/transcode_to_video/:id", transcodeToVideoHandler, authMiddleware)
|
||||
e.POST("/transcode_to_audio/:id", transcodeToAudioHandler, authMiddleware)
|
||||
|
||||
dataGroup := e.Group("/data")
|
||||
dataGroup.Use(authMiddleware)
|
||||
|
@@ -36,6 +36,19 @@
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="media-card">
|
||||
<form action="/transcode_to_video/{{.original.ID}}" method="post">
|
||||
<input type="hidden" name="original_id" value="{{.original.ID}}">
|
||||
<label for="height-select">Height:</label>
|
||||
<select name="height" id="height-select">
|
||||
<option value="144">144p</option>
|
||||
<option value="240">240p</option>
|
||||
<option value="360">360p</option>
|
||||
</select>
|
||||
|
||||
<button type="submit">Transcode</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media-grid">
|
||||
{{range .audios}}
|
||||
@@ -59,6 +72,18 @@
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="media-card">
|
||||
<form action="/transcode_to_audio/{{.original.ID}}" method="post">
|
||||
<input type="hidden" name="original_id" value="{{.original.ID}}">
|
||||
<label for="kbps-select">Kbps:</label>
|
||||
<select name="kbps" id="kbps-select">
|
||||
<option value="64">64 kbps</option>
|
||||
<option value="96">96 kbps</option>
|
||||
</select>
|
||||
|
||||
<button type="submit">Transcode</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user