238 lines
6.4 KiB
Go
238 lines
6.4 KiB
Go
package handlersHTTP
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"git.insit.tech/psa/rtsp_reader-writer/reader/internal/config"
|
||
"git.insit.tech/psa/rtsp_reader-writer/reader/internal/processor"
|
||
"git.insit.tech/psa/rtsp_reader-writer/reader/internal/web/handlers"
|
||
"git.insit.tech/psa/rtsp_reader-writer/writer/pkg/storage"
|
||
"github.com/gofiber/fiber/v2"
|
||
"log"
|
||
"net/http"
|
||
"os"
|
||
)
|
||
|
||
// Download processes Download request.
|
||
func Download(w http.ResponseWriter, r *http.Request) {
|
||
log.Printf("new download request: %+v\n", r)
|
||
|
||
downloadRequest := handlers.VideoRequest{}
|
||
|
||
err := json.NewDecoder(r.Body).Decode(&downloadRequest)
|
||
if err != nil {
|
||
log.Printf("json decode error: %v\n", err)
|
||
w.WriteHeader(http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
pathFileNameRes, err := processor.Process(downloadRequest.Date, downloadRequest.StartTime, downloadRequest.EndTime)
|
||
if err != nil {
|
||
log.Printf("process error: %v\n", err)
|
||
w.WriteHeader(http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
w.Header().Set("Content-Type", "video/mp4")
|
||
// Разрешаем частичную загрузку (поддержка перемотки)
|
||
w.Header().Set("Accept-Ranges", "bytes")
|
||
|
||
http.ServeFile(w, r, pathFileNameRes)
|
||
}
|
||
|
||
// HLS processes Download request.
|
||
func HLS(w http.ResponseWriter, r *http.Request) {
|
||
log.Printf("new hls request: %+v\n", r)
|
||
|
||
path := "/home/psa/GoRepository/data/1280x720/"
|
||
|
||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||
http.StripPrefix("/hls", http.FileServer(http.Dir(path))).ServeHTTP(w, r)
|
||
}
|
||
|
||
// ConfigVodsHandler returns configuration of the requested VOD location.
|
||
//
|
||
// This method allows to get a single VOD location.
|
||
func ConfigVodsHandler(c *fiber.Ctx) error {
|
||
// Read camera id.
|
||
id := c.Params("id")
|
||
|
||
// Get resolutions.
|
||
resolutions, err := storage.GetResolutions(id)
|
||
if err != nil {
|
||
return c.SendStatus(fiber.StatusBadRequest)
|
||
}
|
||
|
||
// Calculate response fields.
|
||
|
||
// Create path to first resolution.
|
||
resDir := fmt.Sprintf("%s/%s/%s", config.DirData, id, resolutions[0])
|
||
|
||
// Read directory.
|
||
entries, err := os.ReadDir(resDir)
|
||
if err != nil {
|
||
return c.SendStatus(fiber.StatusInternalServerError)
|
||
}
|
||
|
||
// Check if a folder has files that was not created or modified for last 5 minutes.
|
||
disabled, err := handlers.Inactive5Minutes(entries)
|
||
if err != nil {
|
||
return c.SendStatus(fiber.StatusInternalServerError)
|
||
}
|
||
|
||
// Calculate the difference between first existing rec file and the last one in milliseconds.
|
||
segmentDuration, err := handlers.RecDurationMilliseconds(entries)
|
||
if err != nil {
|
||
return c.SendStatus(fiber.StatusInternalServerError)
|
||
}
|
||
|
||
// Prepare the Response.
|
||
VodsRes := handlers.ConfigVodsResponse{
|
||
Prefix: id,
|
||
AutoMbr: false, // Always false. Temporary.
|
||
Disabled: disabled,
|
||
SegmentDuration: segmentDuration,
|
||
AddAudioOnly: false, // Always false. Temporary.
|
||
Provider: "Insit",
|
||
}
|
||
|
||
// Write header and code response.
|
||
return c.JSON(VodsRes)
|
||
}
|
||
|
||
// DelVodsHandler delete archive of the requested VOD location.
|
||
//
|
||
// This method delete a single VOD location by its prefix.
|
||
func DelVodsHandler(c *fiber.Ctx) error {
|
||
// Read camera id.
|
||
id := c.Params("id")
|
||
|
||
err := os.Remove(fmt.Sprintf("%s/%s", config.DirData, id))
|
||
if err != nil {
|
||
return c.SendStatus(fiber.StatusBadRequest)
|
||
}
|
||
|
||
return c.SendStatus(fiber.StatusNoContent)
|
||
}
|
||
|
||
// ListFilesVodsHandler returns the list of all files and folders in archive for a specific VOD location.
|
||
//
|
||
// This method allows to get the list of all files and folders for a specific VOD location.
|
||
func ListFilesVodsHandler(c *fiber.Ctx) error {
|
||
// Read camera id.
|
||
id := c.Params("id")
|
||
|
||
// Create map for response.
|
||
files := make(map[string][]string)
|
||
|
||
// Get resolutions.
|
||
resolutions, err := storage.GetResolutions(id)
|
||
if err != nil {
|
||
return c.SendStatus(fiber.StatusBadRequest)
|
||
}
|
||
|
||
for _, resolution := range resolutions {
|
||
// Create path to the resolutions.
|
||
resDir := fmt.Sprintf("%s/%s/%s", config.DirData, id, resolution)
|
||
|
||
// Read directory.
|
||
entries, err := os.ReadDir(resDir)
|
||
if err != nil {
|
||
return c.SendStatus(fiber.StatusInternalServerError)
|
||
}
|
||
|
||
// Create slice for files in folders.
|
||
filesInFolder := make([]string, 0)
|
||
|
||
// Add all files to the slice with files.
|
||
for _, entry := range entries {
|
||
filesInFolder = append(filesInFolder, entry.Name())
|
||
}
|
||
|
||
// Add resolution and all files to the response map.
|
||
files[resolution] = filesInFolder
|
||
}
|
||
|
||
// Prepare the Response.
|
||
vodsRes := handlers.ListVodsResponse{
|
||
EstimatedCount: len(files),
|
||
Files: files,
|
||
}
|
||
|
||
// Write header and code response.
|
||
return c.JSON(vodsRes)
|
||
}
|
||
|
||
// SingleVodsHandler returns a specific file in archive for a specific resolution and VOD location.
|
||
//
|
||
// This method allows to get a single VOD file.
|
||
func SingleVodsHandler(c *fiber.Ctx) error {
|
||
// Read camera id, res, filename.
|
||
id := c.Params("id")
|
||
res := c.Params("res")
|
||
file := c.Params("file")
|
||
|
||
// Calculate file size in bytes.
|
||
FileBytes, err := storage.FileBytes(id, res, file)
|
||
if err != nil {
|
||
return c.SendStatus(fiber.StatusBadRequest)
|
||
}
|
||
|
||
dur, tracks, err := storage.GetDurAndTracks(id, res, file)
|
||
if err != nil {
|
||
return c.SendStatus(fiber.StatusInternalServerError)
|
||
}
|
||
|
||
media := handlers.MediaSingleVodsResponse{
|
||
Tracks: tracks,
|
||
Duration: dur,
|
||
Provider: "Insit",
|
||
Title: id,
|
||
}
|
||
|
||
// Prepare the Response.
|
||
vodsRes := handlers.SingleVodsResponse{
|
||
Name: file,
|
||
Prefix: id,
|
||
Url: c.OriginalURL(),
|
||
Folder: res,
|
||
Bytes: FileBytes,
|
||
MediaInfo: media,
|
||
}
|
||
|
||
// Write header and code response.
|
||
return c.JSON(vodsRes)
|
||
}
|
||
|
||
// DelSingleVodsHandler deletes a VOD file by its name.
|
||
//
|
||
// This method deletes a VOD file by its name.
|
||
func DelSingleVodsHandler(c *fiber.Ctx) error {
|
||
// Read camera id, res, filename.
|
||
id := c.Params("id")
|
||
res := c.Params("res")
|
||
file := c.Params("file")
|
||
|
||
if err := os.Remove(fmt.Sprintf("%s/%s/%s/%s", config.DirData, id, res, file)); err != nil {
|
||
return c.SendStatus(fiber.StatusNotFound)
|
||
}
|
||
|
||
return c.SendStatus(fiber.StatusNoContent)
|
||
}
|
||
|
||
/*
|
||
// FileHandler обработчик для работы с файлами
|
||
func FileHandler(c *fiber.Ctx) error {
|
||
// Если запрос содержит session_id - получаем файл
|
||
sessionData := c.Locals(ContextKeySession).(*SessionData)
|
||
|
||
// Логика получения файла
|
||
fileContent, err := getFileContent(sessionData.FileName)
|
||
if err != nil {
|
||
return c.Status(fiber.StatusNotFound).SendString("File not found")
|
||
}
|
||
|
||
return c.Send(fileContent)
|
||
}
|
||
*/
|