2021-02-23 16:01:29 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2022-05-05 15:46:59 +00:00
|
|
|
"encoding/json"
|
2021-02-23 16:01:29 +00:00
|
|
|
"fmt"
|
2022-12-25 22:19:04 +00:00
|
|
|
"net/http"
|
2021-02-23 16:01:29 +00:00
|
|
|
"net/url"
|
2021-09-16 20:38:28 +00:00
|
|
|
"openmediacenter/apiGo/api/api"
|
2021-02-23 16:01:29 +00:00
|
|
|
"openmediacenter/apiGo/api/types"
|
2021-09-09 21:33:04 +00:00
|
|
|
"openmediacenter/apiGo/config"
|
2021-02-23 16:01:29 +00:00
|
|
|
"openmediacenter/apiGo/database"
|
2022-12-25 22:19:04 +00:00
|
|
|
"openmediacenter/apiGo/videoparser/hls"
|
2021-08-29 17:48:03 +00:00
|
|
|
"os"
|
2022-12-25 22:19:04 +00:00
|
|
|
"os/exec"
|
2021-02-23 16:01:29 +00:00
|
|
|
"strconv"
|
2022-05-05 15:46:59 +00:00
|
|
|
"strings"
|
2021-02-23 16:01:29 +00:00
|
|
|
)
|
|
|
|
|
2021-09-21 08:45:52 +00:00
|
|
|
func addVideoHandlers() {
|
2021-02-23 16:01:29 +00:00
|
|
|
getVideoHandlers()
|
|
|
|
loadVideosHandlers()
|
|
|
|
addToVideoHandlers()
|
|
|
|
}
|
|
|
|
|
|
|
|
func getVideoHandlers() {
|
2021-05-22 19:33:32 +00:00
|
|
|
/**
|
|
|
|
* @api {post} /api/video [getMovies]
|
|
|
|
* @apiDescription Request available Videos
|
|
|
|
* @apiName GetMovies
|
|
|
|
* @apiGroup video
|
|
|
|
*
|
2021-06-08 18:12:09 +00:00
|
|
|
* @apiParam {int} [Tag=1] id of VideoTag to get videos (1=all)
|
2021-05-22 19:33:32 +00:00
|
|
|
*
|
2021-06-08 18:12:09 +00:00
|
|
|
* @apiSuccess {Object[]} Videos List of Videos
|
|
|
|
* @apiSuccess {number} Videos.MovieId Id of Video
|
|
|
|
* @apiSuccess {String} Videos.MovieName Name of video
|
|
|
|
* @apiSuccess {String} TagName Name of the Tag returned
|
2021-05-22 19:33:32 +00:00
|
|
|
*/
|
2021-09-16 20:38:28 +00:00
|
|
|
api.AddHandler("getMovies", api.VideoNode, api.PermUser, func(context api.Context) {
|
2021-05-22 19:33:32 +00:00
|
|
|
var args struct {
|
2021-06-13 20:29:50 +00:00
|
|
|
Tag uint32
|
|
|
|
Sort uint8
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
2021-09-16 20:38:28 +00:00
|
|
|
err := api.DecodeRequest(context.GetRequest(), &args)
|
|
|
|
if err != nil {
|
|
|
|
context.Text("unable to decode request")
|
|
|
|
return
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
|
|
|
|
2021-06-13 20:29:50 +00:00
|
|
|
const (
|
|
|
|
date = iota
|
|
|
|
likes = iota
|
|
|
|
random = iota
|
|
|
|
names = iota
|
2021-07-25 08:15:28 +00:00
|
|
|
length = iota
|
2021-06-13 20:29:50 +00:00
|
|
|
)
|
|
|
|
|
2021-07-25 08:15:28 +00:00
|
|
|
// if wrong number passed no sorting is performed
|
|
|
|
var SortClause = ""
|
2021-06-13 20:29:50 +00:00
|
|
|
switch args.Sort {
|
|
|
|
case date:
|
|
|
|
SortClause = "ORDER BY create_date DESC, movie_name"
|
|
|
|
break
|
|
|
|
case likes:
|
|
|
|
SortClause = "ORDER BY likes DESC"
|
|
|
|
break
|
|
|
|
case random:
|
|
|
|
SortClause = "ORDER BY RAND()"
|
|
|
|
break
|
|
|
|
case names:
|
|
|
|
SortClause = "ORDER BY movie_name"
|
|
|
|
break
|
2021-07-25 08:15:28 +00:00
|
|
|
case length:
|
|
|
|
SortClause = "ORDER BY length DESC"
|
|
|
|
break
|
2021-06-13 20:29:50 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 16:01:29 +00:00
|
|
|
var query string
|
|
|
|
// 1 is the id of the ALL tag
|
2021-05-22 19:33:32 +00:00
|
|
|
if args.Tag != 1 {
|
2021-10-24 13:22:14 +00:00
|
|
|
query = fmt.Sprintf(`SELECT movie_id,movie_name,previewratio,t.tag_name FROM videos
|
2021-02-23 16:01:29 +00:00
|
|
|
INNER JOIN video_tags vt on videos.movie_id = vt.video_id
|
|
|
|
INNER JOIN tags t on vt.tag_id = t.tag_id
|
2021-06-13 20:29:50 +00:00
|
|
|
WHERE t.tag_id = %d %s`, args.Tag, SortClause)
|
2021-02-23 16:01:29 +00:00
|
|
|
} else {
|
2021-10-24 13:22:14 +00:00
|
|
|
query = fmt.Sprintf("SELECT movie_id,movie_name,previewratio, (SELECT 'All' as tag_name) FROM videos %s", SortClause)
|
2021-02-23 16:01:29 +00:00
|
|
|
}
|
|
|
|
|
2021-06-08 18:12:09 +00:00
|
|
|
var result struct {
|
|
|
|
Videos []types.VideoUnloadedType
|
|
|
|
TagName string
|
|
|
|
}
|
|
|
|
|
|
|
|
rows := database.Query(query)
|
|
|
|
vids := []types.VideoUnloadedType{}
|
|
|
|
var name string
|
|
|
|
for rows.Next() {
|
|
|
|
var vid types.VideoUnloadedType
|
2021-10-24 13:22:14 +00:00
|
|
|
err := rows.Scan(&vid.MovieId, &vid.MovieName, &vid.Ratio, &name)
|
2021-06-08 18:12:09 +00:00
|
|
|
if err != nil {
|
2021-09-16 20:38:28 +00:00
|
|
|
return
|
2021-06-08 18:12:09 +00:00
|
|
|
}
|
|
|
|
vids = append(vids, vid)
|
|
|
|
}
|
|
|
|
if rows.Close() != nil {
|
2021-09-16 20:38:28 +00:00
|
|
|
return
|
2021-06-08 18:12:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// if the tag id doesn't exist the query won't return a name
|
|
|
|
if name == "" {
|
2021-09-16 20:38:28 +00:00
|
|
|
return
|
2021-06-08 18:12:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
result.Videos = vids
|
|
|
|
result.TagName = name
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Json(result)
|
2021-02-23 16:01:29 +00:00
|
|
|
})
|
|
|
|
|
2021-05-22 19:33:32 +00:00
|
|
|
/**
|
|
|
|
* @api {post} /api/video [readThumbnail]
|
|
|
|
* @apiDescription Load Thubnail of specific Video
|
|
|
|
* @apiName readThumbnail
|
|
|
|
* @apiGroup video
|
|
|
|
*
|
|
|
|
* @apiParam {int} Movieid id of video to load thumbnail
|
|
|
|
*
|
|
|
|
* @apiSuccess {string} . Base64 encoded Thubnail
|
|
|
|
*/
|
2021-09-16 20:38:28 +00:00
|
|
|
api.AddHandler("readThumbnail", api.VideoNode, api.PermUser, func(context api.Context) {
|
2021-05-22 19:33:32 +00:00
|
|
|
var args struct {
|
|
|
|
Movieid int
|
|
|
|
}
|
2021-09-16 20:38:28 +00:00
|
|
|
err := api.DecodeRequest(context.GetRequest(), &args)
|
|
|
|
if err != nil {
|
|
|
|
context.Text("unable to decode request")
|
|
|
|
return
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 16:01:29 +00:00
|
|
|
var pic []byte
|
|
|
|
|
2021-05-22 19:33:32 +00:00
|
|
|
query := fmt.Sprintf("SELECT thumbnail FROM videos WHERE movie_id=%d", args.Movieid)
|
2021-02-23 16:01:29 +00:00
|
|
|
|
2021-09-16 20:38:28 +00:00
|
|
|
err = database.QueryRow(query).Scan(&pic)
|
2021-02-23 16:01:29 +00:00
|
|
|
if err != nil {
|
2021-05-22 19:33:32 +00:00
|
|
|
fmt.Printf("the thumbnail of movie id %d couldn't be found", args.Movieid)
|
2021-09-16 20:38:28 +00:00
|
|
|
return
|
2021-02-23 16:01:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Text(string(pic))
|
2021-02-23 16:01:29 +00:00
|
|
|
})
|
|
|
|
|
2021-05-22 19:33:32 +00:00
|
|
|
/**
|
|
|
|
* @api {post} /api/video [getRandomMovies]
|
|
|
|
* @apiDescription Load random videos
|
|
|
|
* @apiName getRandomMovies
|
|
|
|
* @apiGroup video
|
|
|
|
*
|
|
|
|
* @apiParam {int} Number number of random videos to load
|
|
|
|
*
|
|
|
|
* @apiSuccess {Object[]} Tags Array of tags occuring in selection
|
|
|
|
* @apiSuccess {string} Tags.TagName Tagname
|
|
|
|
* @apiSuccess {uint32} Tags.TagId Tag ID
|
|
|
|
*
|
|
|
|
* @apiSuccess {Object[]} Videos Array of the videos
|
|
|
|
* @apiSuccess {string} Videos.MovieName Video Name
|
|
|
|
* @apiSuccess {int} Videos.MovieId Video ID
|
|
|
|
*/
|
2021-09-16 20:38:28 +00:00
|
|
|
api.AddHandler("getRandomMovies", api.VideoNode, api.PermUser, func(context api.Context) {
|
2021-05-22 19:33:32 +00:00
|
|
|
var args struct {
|
2022-05-05 15:46:59 +00:00
|
|
|
Number int
|
|
|
|
TagFilter []uint32
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
2021-09-16 20:38:28 +00:00
|
|
|
if api.DecodeRequest(context.GetRequest(), &args) != nil {
|
|
|
|
context.Text("unable to decode request")
|
|
|
|
return
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 16:01:29 +00:00
|
|
|
var result struct {
|
|
|
|
Tags []types.Tag
|
|
|
|
Videos []types.VideoUnloadedType
|
|
|
|
}
|
|
|
|
|
2022-05-05 15:46:59 +00:00
|
|
|
whereclause := "WHERE 1"
|
|
|
|
if len(args.TagFilter) > 0 {
|
|
|
|
d, _ := json.Marshal(args.TagFilter)
|
|
|
|
vals := strings.Trim(string(d), "[]")
|
|
|
|
|
|
|
|
whereclause = fmt.Sprintf("WHERE tag_id IN (%s)", vals)
|
|
|
|
}
|
|
|
|
|
|
|
|
query := fmt.Sprintf(`
|
|
|
|
SELECT video_tags.video_id,v.movie_name FROM video_tags join videos v on v.movie_id = video_tags.video_id
|
|
|
|
%s
|
|
|
|
group by video_id
|
|
|
|
ORDER BY RAND()
|
|
|
|
LIMIT %d`, whereclause, args.Number)
|
2021-02-23 16:01:29 +00:00
|
|
|
result.Videos = readVideosFromResultset(database.Query(query))
|
|
|
|
|
2022-05-05 15:46:59 +00:00
|
|
|
if len(result.Videos) > 0 {
|
|
|
|
var ids string
|
|
|
|
for i := range result.Videos {
|
|
|
|
ids += "video_tags.video_id=" + strconv.Itoa(result.Videos[i].MovieId)
|
2021-02-23 16:01:29 +00:00
|
|
|
|
2022-05-05 15:46:59 +00:00
|
|
|
if i < len(result.Videos)-1 {
|
|
|
|
ids += " OR "
|
|
|
|
}
|
2021-02-23 16:01:29 +00:00
|
|
|
}
|
|
|
|
|
2022-05-05 15:46:59 +00:00
|
|
|
// add the corresponding tags
|
|
|
|
query = fmt.Sprintf(`SELECT t.tag_name,t.tag_id FROM video_tags
|
2021-02-23 16:01:29 +00:00
|
|
|
INNER JOIN tags t on video_tags.tag_id = t.tag_id
|
|
|
|
WHERE %s
|
|
|
|
GROUP BY t.tag_id`, ids)
|
|
|
|
|
2022-05-05 15:46:59 +00:00
|
|
|
rows := database.Query(query)
|
|
|
|
if rows != nil {
|
|
|
|
for rows.Next() {
|
|
|
|
var tag types.Tag
|
|
|
|
err := rows.Scan(&tag.TagName, &tag.TagId)
|
|
|
|
if err != nil {
|
|
|
|
panic(err.Error()) // proper Error handling instead of panic in your app
|
|
|
|
}
|
|
|
|
// append to final array
|
|
|
|
result.Tags = append(result.Tags, tag)
|
|
|
|
}
|
2021-02-23 16:01:29 +00:00
|
|
|
}
|
2022-05-05 15:46:59 +00:00
|
|
|
} else {
|
|
|
|
result.Tags = []types.Tag{}
|
2021-02-23 16:01:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Json(result)
|
2021-02-23 16:01:29 +00:00
|
|
|
})
|
|
|
|
|
2021-05-22 19:33:32 +00:00
|
|
|
/**
|
|
|
|
* @api {post} /api/video [getSearchKeyWord]
|
|
|
|
* @apiDescription Get videos for search keyword
|
|
|
|
* @apiName getSearchKeyWord
|
|
|
|
* @apiGroup video
|
|
|
|
*
|
|
|
|
* @apiParam {string} KeyWord Keyword to search for
|
|
|
|
*
|
|
|
|
* @apiSuccess {Object[]} . List of Videos
|
|
|
|
* @apiSuccess {number} .MovieId Id of Video
|
|
|
|
* @apiSuccess {String} .MovieName Name of video
|
|
|
|
*/
|
2021-09-16 20:38:28 +00:00
|
|
|
api.AddHandler("getSearchKeyWord", api.VideoNode, api.PermUser, func(context api.Context) {
|
2021-05-22 19:33:32 +00:00
|
|
|
var args struct {
|
|
|
|
KeyWord string
|
|
|
|
}
|
2021-09-16 20:38:28 +00:00
|
|
|
if api.DecodeRequest(context.GetRequest(), &args) != nil {
|
|
|
|
context.Text("unable to decode request")
|
|
|
|
return
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
|
|
|
|
2021-02-23 16:01:29 +00:00
|
|
|
query := fmt.Sprintf(`SELECT movie_id,movie_name FROM videos
|
|
|
|
WHERE movie_name LIKE '%%%s%%'
|
2021-05-22 19:33:32 +00:00
|
|
|
ORDER BY likes DESC, create_date DESC, movie_name`, args.KeyWord)
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Json(readVideosFromResultset(database.Query(query)))
|
2021-02-23 16:01:29 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// function to handle stuff for loading specific videos and startdata
|
|
|
|
func loadVideosHandlers() {
|
2021-05-22 19:33:32 +00:00
|
|
|
/**
|
|
|
|
* @api {post} /api/video [loadVideo]
|
|
|
|
* @apiDescription Load all data for a specific video
|
|
|
|
* @apiName loadVideo
|
|
|
|
* @apiGroup video
|
|
|
|
*
|
|
|
|
* @apiParam {int} MovieId ID of video
|
|
|
|
*
|
|
|
|
* @apiSuccess {string} MovieName Videoname
|
|
|
|
* @apiSuccess {uint32} MovieId Video ID
|
|
|
|
* @apiSuccess {string} MovieUrl Url to video file
|
|
|
|
* @apiSuccess {string} Poster Base64 encoded Poster
|
|
|
|
* @apiSuccess {uint64} Likes Number of likes
|
|
|
|
* @apiSuccess {uint16} Quality Video FrameWidth
|
|
|
|
* @apiSuccess {uint16} Length Video Length in seconds
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @apiSuccess {Object[]} Tags Array of tags of video
|
|
|
|
* @apiSuccess {string} Tags.TagName Tagname
|
|
|
|
* @apiSuccess {uint32} Tags.TagId Tag ID
|
|
|
|
*
|
|
|
|
* @apiSuccess {Object[]} SuggestedTag Array of tags for quick add suggestions
|
|
|
|
* @apiSuccess {string} SuggestedTag.TagName Tagname
|
|
|
|
* @apiSuccess {uint32} SuggestedTag.TagId Tag ID
|
|
|
|
*
|
|
|
|
* @apiSuccess {Object[]} Actors Array of Actors playing in this video
|
|
|
|
* @apiSuccess {uint32} Actors.ActorId Actor Id
|
|
|
|
* @apiSuccess {string} Actors.Name Actor Name
|
|
|
|
* @apiSuccess {string} Actors.Thumbnail Portrait Thumbnail
|
|
|
|
*/
|
2021-09-16 20:38:28 +00:00
|
|
|
api.AddHandler("loadVideo", api.VideoNode, api.PermUser, func(context api.Context) {
|
2021-05-22 19:33:32 +00:00
|
|
|
var args struct {
|
|
|
|
MovieId int
|
|
|
|
}
|
2021-09-16 20:38:28 +00:00
|
|
|
if api.DecodeRequest(context.GetRequest(), &args) != nil {
|
|
|
|
context.Text("unable to decode request")
|
|
|
|
return
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 08:52:18 +00:00
|
|
|
query := fmt.Sprintf(`SELECT movie_name,movie_url,movie_id,thumbnail,poster,likes,quality,length,release_date
|
2021-05-22 19:33:32 +00:00
|
|
|
FROM videos WHERE movie_id=%d`, args.MovieId)
|
2021-02-23 16:01:29 +00:00
|
|
|
|
|
|
|
var res types.FullVideoType
|
|
|
|
var poster []byte
|
|
|
|
var thumbnail []byte
|
|
|
|
|
2021-09-28 08:52:18 +00:00
|
|
|
err := database.QueryRow(query).Scan(&res.MovieName, &res.MovieUrl, &res.MovieId, &thumbnail, &poster, &res.Likes, &res.Quality, &res.Length, &res.ReleaseDate)
|
2021-02-23 16:01:29 +00:00
|
|
|
if err != nil {
|
2021-09-16 20:38:28 +00:00
|
|
|
fmt.Printf("Error getting full data list of videoid - %d", args.MovieId)
|
2021-02-23 16:01:29 +00:00
|
|
|
fmt.Println(err.Error())
|
2021-09-16 20:38:28 +00:00
|
|
|
return
|
2021-02-23 16:01:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// we ned to urlencode the movieurl
|
|
|
|
res.MovieUrl = url.PathEscape(res.MovieUrl)
|
|
|
|
|
|
|
|
// we need to stringify the pic byte array
|
|
|
|
res.Poster = string(poster)
|
|
|
|
|
|
|
|
// if poster in db is empty we use the thumbnail
|
|
|
|
if res.Poster == "" {
|
|
|
|
res.Poster = string(thumbnail)
|
|
|
|
}
|
|
|
|
|
|
|
|
// now add the tags of this video
|
|
|
|
query = fmt.Sprintf(`SELECT t.tag_id, t.tag_name FROM video_tags
|
|
|
|
INNER JOIN tags t on video_tags.tag_id = t.tag_id
|
|
|
|
WHERE video_tags.video_id=%d
|
2021-05-22 19:33:32 +00:00
|
|
|
GROUP BY t.tag_id`, args.MovieId)
|
2021-02-23 16:01:29 +00:00
|
|
|
|
|
|
|
res.Tags = readTagsFromResultset(database.Query(query))
|
|
|
|
|
|
|
|
query = fmt.Sprintf(`SELECT * FROM tags
|
|
|
|
WHERE tag_id NOT IN (
|
|
|
|
SELECT video_tags.tag_id FROM video_tags
|
|
|
|
WHERE video_id=%d)
|
|
|
|
ORDER BY rand()
|
2021-05-22 19:33:32 +00:00
|
|
|
LIMIT 5`, args.MovieId)
|
2021-02-23 16:01:29 +00:00
|
|
|
|
|
|
|
res.SuggestedTag = readTagsFromResultset(database.Query(query))
|
|
|
|
|
|
|
|
// query the actors corresponding to video
|
|
|
|
query = fmt.Sprintf(`SELECT a.actor_id, name, thumbnail FROM actors_videos
|
|
|
|
JOIN actors a on actors_videos.actor_id = a.actor_id
|
2021-05-22 19:33:32 +00:00
|
|
|
WHERE actors_videos.video_id=%d`, args.MovieId)
|
2021-02-23 16:01:29 +00:00
|
|
|
|
|
|
|
res.Actors = readActorsFromResultset(database.Query(query))
|
|
|
|
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Json(res)
|
2021-02-23 16:01:29 +00:00
|
|
|
})
|
|
|
|
|
2021-05-22 19:33:32 +00:00
|
|
|
/**
|
|
|
|
* @api {post} /api/video [getStartData]
|
|
|
|
* @apiDescription Get general video informations at start
|
|
|
|
* @apiName getStartData
|
|
|
|
* @apiGroup video
|
|
|
|
*
|
|
|
|
* @apiSuccess {uint32} VideoNr Total nr of videos
|
|
|
|
* @apiSuccess {uint32} FullHdNr number of FullHD videos
|
|
|
|
* @apiSuccess {uint32} HDNr number of HD videos
|
|
|
|
* @apiSuccess {uint32} SDNr number of SD videos
|
|
|
|
* @apiSuccess {uint32} DifferentTags number of different Tags available
|
|
|
|
* @apiSuccess {uint32} Tagged number of different Tags assigned
|
|
|
|
*/
|
2021-09-16 20:38:28 +00:00
|
|
|
api.AddHandler("getStartData", api.VideoNode, api.PermUser, func(context api.Context) {
|
2021-02-23 16:01:29 +00:00
|
|
|
var result types.StartData
|
|
|
|
// query settings and infotile values
|
|
|
|
query := `
|
|
|
|
SELECT (
|
|
|
|
SELECT COUNT(*) FROM videos
|
|
|
|
) AS videonr,
|
|
|
|
(
|
|
|
|
SELECT COUNT(*) FROM videos
|
|
|
|
INNER JOIN video_tags vt on videos.movie_id = vt.video_id
|
|
|
|
INNER JOIN tags t on vt.tag_id = t.tag_id
|
|
|
|
) AS tagged,
|
|
|
|
(
|
|
|
|
SELECT COUNT(*) FROM video_tags as vt
|
|
|
|
INNER JOIN tags t on vt.tag_id = t.tag_id
|
|
|
|
WHERE t.tag_name='hd'
|
|
|
|
) AS hd,
|
|
|
|
(
|
|
|
|
SELECT COUNT(*) FROM video_tags as vt
|
|
|
|
INNER JOIN tags t on vt.tag_id = t.tag_id
|
|
|
|
WHERE t.tag_name='fullhd'
|
|
|
|
) AS fullhd,
|
|
|
|
(
|
|
|
|
SELECT COUNT(*) FROM video_tags as vt
|
|
|
|
INNER JOIN tags t on vt.tag_id = t.tag_id
|
|
|
|
WHERE t.tag_name='lowquality'
|
|
|
|
) AS lq,
|
|
|
|
(
|
|
|
|
SELECT COUNT(*) as nr FROM tags
|
|
|
|
) as tags
|
|
|
|
LIMIT 1`
|
|
|
|
|
|
|
|
_ = database.QueryRow(query).Scan(&result.VideoNr, &result.Tagged, &result.HDNr, &result.FullHdNr, &result.SDNr, &result.DifferentTags)
|
|
|
|
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Json(result)
|
2021-02-23 16:01:29 +00:00
|
|
|
})
|
2022-12-25 22:19:04 +00:00
|
|
|
|
|
|
|
api.AddHandler("loadM3U8", api.VideoNode, api.PermUnauthorized, func(ctx api.Context) {
|
|
|
|
param := ctx.GetRequest().URL.Query().Get("id")
|
|
|
|
id, _ := strconv.Atoi(param)
|
|
|
|
|
|
|
|
mylist :=
|
|
|
|
`#EXTM3U
|
|
|
|
#EXT-X-VERSION:4
|
|
|
|
#EXT-X-MEDIA-SEQUENCE:0
|
|
|
|
#EXT-X-ALLOW-CACHE:NO
|
|
|
|
#EXT-X-TARGETDURATION:10
|
|
|
|
#EXT-X-START:TIME-OFFSET=0
|
|
|
|
#EXT-X-PLAYLIST-TYPE:VOD
|
|
|
|
`
|
|
|
|
// ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
|
|
|
|
cmd := exec.Command("ffprobe",
|
|
|
|
"-v", "error",
|
|
|
|
"-show_entries", "format=duration",
|
|
|
|
"-of", "default=noprint_wrappers=1:nokey=1",
|
|
|
|
hls.GetVideoPathById(uint32(id)))
|
|
|
|
stdout, err := cmd.Output()
|
|
|
|
//
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
fmt.Println(string(err.(*exec.ExitError).Stderr))
|
|
|
|
}
|
|
|
|
secss, _, _ := strings.Cut(string(stdout), ".")
|
|
|
|
secsi, err := strconv.Atoi(secss)
|
|
|
|
|
|
|
|
i := 0
|
|
|
|
for ; i < secsi/10; i++ {
|
|
|
|
mylist += fmt.Sprintf(
|
|
|
|
`#EXTINF:10.0,
|
|
|
|
/api/video/getVideoSegment?id=%d&idx=%d
|
|
|
|
`, id, i)
|
|
|
|
}
|
|
|
|
mylist += fmt.Sprintf(
|
|
|
|
`#EXTINF:%s,
|
|
|
|
/api/video/getVideoSegment?id=%d&idx=%d
|
|
|
|
EXT-X-ENDLIST
|
|
|
|
`, fmt.Sprintf("%d.0", secsi%10), id, i)
|
|
|
|
ctx.Text(mylist)
|
|
|
|
})
|
|
|
|
|
|
|
|
api.AddHandler("getVideoSegment", api.VideoNode, api.PermUnauthorized, func(ctx api.Context) {
|
|
|
|
params := ctx.GetRequest().URL.Query()
|
|
|
|
idxs := params.Get("idx")
|
|
|
|
ids := params.Get("id")
|
|
|
|
|
|
|
|
id, _ := strconv.Atoi(ids)
|
|
|
|
idx, _ := strconv.Atoi(idxs)
|
|
|
|
// todo error handling
|
|
|
|
|
|
|
|
tmppath := hls.GetSegment(uint32(idx), uint32(id))
|
|
|
|
http.ServeFile(ctx.GetWriter(), ctx.GetRequest(), tmppath)
|
|
|
|
})
|
2021-02-23 16:01:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func addToVideoHandlers() {
|
2021-05-22 19:33:32 +00:00
|
|
|
/**
|
|
|
|
* @api {post} /api/video [addLike]
|
|
|
|
* @apiDescription Add a like to a video
|
|
|
|
* @apiName addLike
|
|
|
|
* @apiGroup video
|
|
|
|
*
|
|
|
|
* @apiParam {int} MovieId ID of video
|
|
|
|
*
|
2021-09-16 20:38:28 +00:00
|
|
|
* @apiSuccess {string} result 'success' if successfully or Error message if not
|
2021-05-22 19:33:32 +00:00
|
|
|
*/
|
2021-09-16 20:38:28 +00:00
|
|
|
api.AddHandler("addLike", api.VideoNode, api.PermUser, func(context api.Context) {
|
2021-05-22 19:33:32 +00:00
|
|
|
var args struct {
|
|
|
|
MovieId int
|
|
|
|
}
|
2021-09-16 20:38:28 +00:00
|
|
|
if api.DecodeRequest(context.GetRequest(), &args) != nil {
|
|
|
|
context.Text("unable to decode request")
|
|
|
|
return
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
query := fmt.Sprintf("update videos set likes = likes + 1 where movie_id = %d", args.MovieId)
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Text(string(database.SuccessQuery(query)))
|
2021-02-23 16:01:29 +00:00
|
|
|
})
|
|
|
|
|
2021-05-22 19:33:32 +00:00
|
|
|
/**
|
|
|
|
* @api {post} /api/video [deleteVideo]
|
|
|
|
* @apiDescription Delete a specific video from database
|
|
|
|
* @apiName deleteVideo
|
|
|
|
* @apiGroup video
|
|
|
|
*
|
|
|
|
* @apiParam {int} MovieId ID of video
|
2021-09-03 10:09:51 +00:00
|
|
|
* @apiParam {bool} FullyDelete Delete video from disk?
|
2021-05-22 19:33:32 +00:00
|
|
|
*
|
2021-09-16 20:38:28 +00:00
|
|
|
* @apiSuccess {string} result 'success' if successfully or Error message if not
|
2021-05-22 19:33:32 +00:00
|
|
|
*/
|
2021-09-16 20:38:28 +00:00
|
|
|
api.AddHandler("deleteVideo", api.VideoNode, api.PermUser, func(context api.Context) {
|
2021-05-22 19:33:32 +00:00
|
|
|
var args struct {
|
2021-08-29 17:48:03 +00:00
|
|
|
MovieId int
|
|
|
|
FullyDelete bool
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
2021-09-16 20:38:28 +00:00
|
|
|
if api.DecodeRequest(context.GetRequest(), &args) != nil {
|
|
|
|
context.Text("unable to decode request")
|
|
|
|
return
|
2021-05-22 19:33:32 +00:00
|
|
|
}
|
|
|
|
|
2021-03-14 15:56:26 +00:00
|
|
|
// delete tag constraints
|
2021-05-22 19:33:32 +00:00
|
|
|
query := fmt.Sprintf("DELETE FROM video_tags WHERE video_id=%d", args.MovieId)
|
2021-03-14 15:56:26 +00:00
|
|
|
err := database.Edit(query)
|
|
|
|
|
|
|
|
// delete actor constraints
|
2021-05-22 19:33:32 +00:00
|
|
|
query = fmt.Sprintf("DELETE FROM actors_videos WHERE video_id=%d", args.MovieId)
|
2021-03-14 15:56:26 +00:00
|
|
|
err = database.Edit(query)
|
|
|
|
|
|
|
|
// respond only if result not successful
|
|
|
|
if err != nil {
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Text(string(database.ManualSuccessResponse(err)))
|
2021-03-14 15:56:26 +00:00
|
|
|
}
|
|
|
|
|
2021-09-03 10:09:51 +00:00
|
|
|
// only allow deletion of video if cli flag is set, independent of passed api arg
|
2021-09-09 21:33:04 +00:00
|
|
|
if config.GetConfig().Features.FullyDeletableVideos && args.FullyDelete {
|
2021-08-29 17:48:03 +00:00
|
|
|
// get physical path of video to delete
|
|
|
|
query = fmt.Sprintf("SELECT movie_url FROM videos WHERE movie_id=%d", args.MovieId)
|
|
|
|
var vidpath string
|
|
|
|
err := database.QueryRow(query).Scan(&vidpath)
|
|
|
|
if err != nil {
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Text(string(database.ManualSuccessResponse(err)))
|
2021-08-29 17:48:03 +00:00
|
|
|
}
|
|
|
|
|
2021-09-05 13:27:14 +00:00
|
|
|
sett, videoprefix, _ := database.GetSettings()
|
|
|
|
assembledPath := videoprefix + sett.VideoPath + vidpath
|
2021-09-05 13:01:11 +00:00
|
|
|
|
|
|
|
err = os.Remove(assembledPath)
|
2021-08-29 17:48:03 +00:00
|
|
|
if err != nil {
|
2021-09-05 13:01:11 +00:00
|
|
|
fmt.Printf("unable to delete file: %s -- %s\n", assembledPath, err.Error())
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Text(string(database.ManualSuccessResponse(err)))
|
2021-08-29 17:48:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// delete video row from db
|
2021-05-22 19:33:32 +00:00
|
|
|
query = fmt.Sprintf("DELETE FROM videos WHERE movie_id=%d", args.MovieId)
|
2021-09-16 20:38:28 +00:00
|
|
|
context.Text(string(database.SuccessQuery(query)))
|
2021-02-23 16:01:29 +00:00
|
|
|
})
|
|
|
|
}
|