Added VOD handler.
This commit is contained in:
parent
2c57eabb0d
commit
670e27f9c4
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,3 +6,4 @@
|
||||
*.avi
|
||||
/archived_writer/
|
||||
/tester/
|
||||
/reader/html/
|
||||
|
30
reader/cmd/main.go
Normal file
30
reader/cmd/main.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"reader/pkg/handlers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
path := "/home/psa/GoRepository/"
|
||||
port := 8080
|
||||
|
||||
http.HandleFunc("GET /download", handlers.Download) // example request: {"date": "07-03-2025", "start_time": "16-43", "end_time": "16-44"}
|
||||
http.HandleFunc("GET /hls", handlers.HLS)
|
||||
//http.Handle("/", addHeaders(http.FileServer(http.Dir(path))))
|
||||
|
||||
log.Println("Starting server on:")
|
||||
log.Printf("Serving %s on HTTP port: %d\n", path, port)
|
||||
|
||||
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
|
||||
|
||||
}
|
||||
|
||||
//func addHeaders(h http.Handler) http.Handler {
|
||||
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
// h.ServeHTTP(w, r)
|
||||
// })
|
||||
//}
|
5
reader/go.mod
Normal file
5
reader/go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module reader
|
||||
|
||||
go 1.23.6
|
||||
|
||||
require git.insit.tech/sas/rtsp_proxy v0.0.0-20250310124520-82fa76149f4e // indirect
|
2
reader/go.sum
Normal file
2
reader/go.sum
Normal file
@ -0,0 +1,2 @@
|
||||
git.insit.tech/sas/rtsp_proxy v0.0.0-20250310124520-82fa76149f4e h1:JeOZvcZA4JHfoBG5ES9tpSHrhOj1jmjFzSJAyKIjApU=
|
||||
git.insit.tech/sas/rtsp_proxy v0.0.0-20250310124520-82fa76149f4e/go.mod h1:9Yw6g7jcG9fIkWh6FGXSWTyZs4d7EQWaRhdKnnH2TvA=
|
238
reader/internal/processor/file.go
Normal file
238
reader/internal/processor/file.go
Normal file
@ -0,0 +1,238 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// partitionTime convert numbers from type STRING to type INT.
|
||||
func partitionTime(time string) (startHour int, startMinute int, err error) {
|
||||
// Part hours and minutes.
|
||||
s := []byte(time)
|
||||
h := []byte{s[0], s[1]}
|
||||
m := []byte{s[3], s[4]}
|
||||
|
||||
// Transforms hours and minutes into INTs.
|
||||
startHour, err = strconv.Atoi(string(h))
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
startMinute, err = strconv.Atoi(string(m))
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
return startHour, startMinute, nil
|
||||
}
|
||||
|
||||
// createTXT collects filenames into TXT file.
|
||||
func createTXT(path, date, startTime, endTime string) (string, error) {
|
||||
//fileNames := make([]string, 0)
|
||||
|
||||
fileNameTXT := startTime + "_" + endTime + ".txt"
|
||||
f, err := os.Create(path + fileNameTXT)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("create file error: %s", err.Error())
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Read the directory.
|
||||
dirEntry, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("read directory error: %s", err.Error())
|
||||
}
|
||||
|
||||
// Calculate start time and end time of the required fragment.
|
||||
startHour, startMinute, endHour, endMinute := calcNeededTime(startTime, endTime)
|
||||
|
||||
for i := startHour; i <= endHour; i++ {
|
||||
for j := startMinute; j < endMinute; j++ { // exclude the last minute as endMinute is the final time
|
||||
for _, entry := range dirEntry {
|
||||
if strings.Contains(entry.Name(), strconv.Itoa(i)+"-"+strconv.Itoa(j)+"-00"+"_"+date) {
|
||||
_, err = f.WriteString("file '" + entry.Name() + "'\n")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("write file error: %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fileNameTXT, nil
|
||||
}
|
||||
|
||||
// mergeFiles merges the collected files into one MP4 file.
|
||||
func mergeFiles(path, fileNamesTXT string) (string, error) {
|
||||
fileNameRes := time.Now().Format("15-04-05") + "_video.mp4"
|
||||
|
||||
cmd := exec.Command("ffmpeg",
|
||||
"-f", "concat",
|
||||
"-safe", "0",
|
||||
"-fflags", "+genpts",
|
||||
"-i", path+fileNamesTXT,
|
||||
"-c", "copy",
|
||||
path+fileNameRes)
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("merge files error: %s", err.Error())
|
||||
}
|
||||
|
||||
return fileNameRes, nil
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// Функция copyFile находит файл в репозитории и создает его копию.
|
||||
//func copyFiles(path string, filename []string) (filenameCopied []string, err error) {
|
||||
// for i := 0; i < len(filename); i++ {
|
||||
// input, err := os.Open(path + filename[i])
|
||||
// if err != nil {
|
||||
// log.Println("Ошибка открытия input файла: ", err)
|
||||
// }
|
||||
// defer func() {
|
||||
// err = input.Close()
|
||||
// if err != nil {
|
||||
// log.Println("Ошибка закрытия input файла.")
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
// output, err := os.Create(time.Now().Format("15-04-05") + "video.mkv")
|
||||
// if err != nil {
|
||||
// log.Println("Ошибка создания output файла: ", err)
|
||||
// }
|
||||
// defer func() {
|
||||
// err = output.Close()
|
||||
// if err != nil {
|
||||
// log.Println("Ошибка закрытия output файла.")
|
||||
// }
|
||||
//
|
||||
// }()
|
||||
//
|
||||
// _, err = io.Copy(output, input)
|
||||
// if err != nil {
|
||||
// log.Println("Ошибка копирования файла")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// log.Println("Файлы скопированы.")
|
||||
// return filename, err
|
||||
//}
|
||||
//
|
||||
//// MergeMKV принимает названия видеофайлов для объединения.
|
||||
//func MergeMKV(filenames ...string) {
|
||||
// // Создание файла со списком видеофайлов для объединения
|
||||
// f, err := os.Create("videoList.txt")
|
||||
// if err != nil {
|
||||
// log.Fatalln("Ошибка создания файла со списком видеофайлов для объединения", err)
|
||||
// }
|
||||
// defer func() {
|
||||
// err = f.Close()
|
||||
// if err != nil {
|
||||
// log.Fatalln("Ошибка закрытия файла: ", err.Error())
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
// // Запись видеофайлов для объединения
|
||||
// n := len(filenames)
|
||||
//
|
||||
// for i := 0; i < n; i++ {
|
||||
// _, err = f.WriteString("file '" + filenames[i] + "'\n")
|
||||
// if err != nil {
|
||||
// log.Fatalln(err)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// err = mergeFfmpeg(f)
|
||||
// if err != nil {
|
||||
// log.Fatalln("Ошибка объединения видеофайлов с помощью ffmpeg: ", err)
|
||||
// }
|
||||
//
|
||||
// err = os.Remove("videoList.txt")
|
||||
// if err != nil {
|
||||
// log.Println("Ошибка удаления временного файла videoList.txt: ", err)
|
||||
// }
|
||||
// log.Println("Временный файл videoList.txt успешно удален")
|
||||
//}
|
||||
//
|
||||
//// DeleteTrimmedFragments удаляет временно созданные файлы.
|
||||
//func DeleteTrimmedFragments(filenames ...string) {
|
||||
// n := len(filenames)
|
||||
//
|
||||
// for i := 0; i < n; i++ {
|
||||
// err := os.Remove(filenames[i])
|
||||
// if err != nil {
|
||||
// log.Printf("Ошибка удаления временного файла %s: %s", filenames[i], err.Error())
|
||||
// }
|
||||
// log.Printf("Временный файл %s успешно удален", filenames[i])
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//
|
||||
//// createFilename forms first part of the filename which contains time and date.
|
||||
//func createFilename(time, date string) (fileName string) {
|
||||
// s := []byte(time)
|
||||
// s[3], s[4] = '0', '0'
|
||||
// fileName = string(s) + "_" + date
|
||||
// return fileName
|
||||
//}
|
||||
//
|
||||
//// Добавление одного часа к строке в формате ЧЧ-ММ
|
||||
//func addHour(startTime string) (fileName string) {
|
||||
// s := []byte(startTime)
|
||||
// if s[0] == '0' && s[1] == '9' {
|
||||
// s[0] = '1'
|
||||
// s[1] = '0'
|
||||
// } else if s[0] == '1' && s[1] == '9' {
|
||||
// s[0] = '2'
|
||||
// s[1] = '0'
|
||||
// } else {
|
||||
// s[1]++
|
||||
// }
|
||||
// fileName = string(s)
|
||||
// return fileName
|
||||
//}
|
||||
//
|
||||
//// Проверка наличия файла
|
||||
//func checkFile(path, fileName string) (string, error) {
|
||||
// found := false
|
||||
// filenameIn := fileName
|
||||
//
|
||||
// dirEntry, err := os.ReadDir(path)
|
||||
// if err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
// for _, entry := range dirEntry {
|
||||
// if strings.Contains(entry.Name(), filenameIn) {
|
||||
// filenameIn = entry.Name()
|
||||
// break
|
||||
// }
|
||||
// return "", fmt.Errorf("file %s not found", filenameIn)
|
||||
// }
|
||||
//
|
||||
// err = filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {
|
||||
// if err != nil {
|
||||
// return err // Возвращаем ошибку, если возникла
|
||||
// }
|
||||
// if !info.IsDir() && info.Name() == filenameIn {
|
||||
// log.Println("Файл обнаружен:", filePath)
|
||||
// found = true
|
||||
// return filepath.SkipDir // Останавливаем обход после нахождения
|
||||
// }
|
||||
// return nil
|
||||
// })
|
||||
//
|
||||
// if err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
//
|
||||
// if !found {
|
||||
// return "", errors.New("file not found")
|
||||
// }
|
||||
//
|
||||
// return filenameIn, nil
|
||||
//}
|
26
reader/internal/processor/proc.go
Normal file
26
reader/internal/processor/proc.go
Normal file
@ -0,0 +1,26 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func Process(date, startTime, endTime string) (string, error) {
|
||||
// Set path with the records.
|
||||
path := "/home/psa/GoRepository/data/1280x720/"
|
||||
|
||||
// Collect filenames into TXT file.
|
||||
fileNamesTXT, err := createTXT(path, date, startTime, endTime)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("collect filenames into TXT file error: %s", err.Error())
|
||||
}
|
||||
|
||||
// Merge the collected files into one MP4 file.
|
||||
fileNameRes, err := mergeFiles(path, fileNamesTXT)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("merge files error: %s", err.Error())
|
||||
}
|
||||
|
||||
pathFileNameRes := path + fileNameRes
|
||||
|
||||
return pathFileNameRes, nil
|
||||
}
|
47
reader/internal/processor/time.go
Normal file
47
reader/internal/processor/time.go
Normal file
@ -0,0 +1,47 @@
|
||||
package processor
|
||||
|
||||
import "log"
|
||||
|
||||
// calcNeededTime accepts the start and the end of the recording time, converts the time from the format STRING to the
|
||||
// format INT and returns the hour and the minute of the start recording time, the hour and the minute of the end
|
||||
// recording time.
|
||||
func calcNeededTime(startTime, endTime string) (startHour, startMinute, endHour, endMinute int) {
|
||||
// Calc needed time.
|
||||
startHour, startMinute, err := partitionTime(startTime)
|
||||
if err != nil {
|
||||
log.Fatal("Ошибка конвертации: ", err)
|
||||
}
|
||||
endHour, endMinute, err = partitionTime(endTime)
|
||||
if err != nil {
|
||||
log.Fatal("Ошибка конвертации: ", err)
|
||||
}
|
||||
|
||||
return startHour, startMinute, endHour, endMinute
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// CalcEndMinuteFirstVideo calculates the need to change the hour (switching one fragment of video recording (which
|
||||
//// lasts 1 hour) to another fragment of video recording) and returns the number of hours (required number of video
|
||||
//// fragments), the duration of minutes (the object responsible for the indicator of minutes) of each fragment for the
|
||||
//// formation of the final video (except for the last video fragment, provided DurationHour > 0 (the third object
|
||||
//// returned by the CalcEndMinuteFirstVideo function)).
|
||||
////
|
||||
//// In the case that you need to take a full fragment of the video file, for example, from 00-00 to 03-00, the
|
||||
//// DurationHour value is conciliated by 1 and returned.
|
||||
//func CalcEndMinuteFirstVideo(durationHour, endMinuteFirstVideo, startHour, endHour, endMinute int) (
|
||||
// durationHourCalc int, endMinuteFirstVideoCalc int) {
|
||||
// durationHour = endHour - startHour
|
||||
//
|
||||
// if durationHour > 0 {
|
||||
// endMinuteFirstVideo = 60
|
||||
// } else {
|
||||
// endMinuteFirstVideo = endMinute
|
||||
// }
|
||||
//
|
||||
// if endMinute == 0 && durationHour > 0 {
|
||||
// durationHour -= 1
|
||||
// }
|
||||
//
|
||||
// return durationHour, endMinuteFirstVideo
|
||||
//}
|
42
reader/internal/processor/video.go
Normal file
42
reader/internal/processor/video.go
Normal file
@ -0,0 +1,42 @@
|
||||
package processor
|
||||
|
||||
//// trimMKV обрезает видеофайл и возвращает название созданного нового файла.
|
||||
//func trimMKV(inputFile, outputFile, startTime, finishTime string) (outputFileTrimmed string) {
|
||||
// outputFile = time.Now().Format("15-04-05") + outputFile
|
||||
//
|
||||
// cmd := exec.Command("ffmpeg",
|
||||
// "-i", inputFile,
|
||||
// "-ss", startTime,
|
||||
// "-to", finishTime,
|
||||
// "-c", "copy",
|
||||
// outputFile)
|
||||
//
|
||||
// err := cmd.Run()
|
||||
//
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//
|
||||
// log.Println("Видео успешно обрезано")
|
||||
// return outputFile
|
||||
//}
|
||||
//
|
||||
//// mergeFfmpeg объединяет видеофайлы с помощью ffmpeg
|
||||
//func mergeFfmpeg(f *os.File) error {
|
||||
// cmd := exec.Command("ffmpeg",
|
||||
// "-f", "concat",
|
||||
// "-safe", "0",
|
||||
// "-i", f.Name(),
|
||||
// "-c", "copy",
|
||||
// time.Now().Format("15-04-05")+"_video.mkv")
|
||||
//
|
||||
// err := cmd.Run()
|
||||
//
|
||||
// if err != nil {
|
||||
// log.Println("Ошибка исполнения запроса ffmpeg: ", err)
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// log.Println("Видео успешно объединено")
|
||||
// return nil
|
||||
//}
|
45
reader/pkg/handlers/handlers.go
Normal file
45
reader/pkg/handlers/handlers.go
Normal file
@ -0,0 +1,45 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"reader/internal/processor"
|
||||
)
|
||||
|
||||
type DownloadRequest struct {
|
||||
Date string `json:"date"`
|
||||
StartTime string `json:"start_time"`
|
||||
EndTime string `json:"end_time"`
|
||||
}
|
||||
|
||||
func Download(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("new download request: %+v\n", r)
|
||||
|
||||
dr := DownloadRequest{}
|
||||
|
||||
err := json.NewDecoder(r.Body).Decode(&dr)
|
||||
if err != nil {
|
||||
log.Printf("json decode error: %v\n", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
pathFileNameRes, err := processor.Process(dr.Date, dr.StartTime, dr.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)
|
||||
}
|
||||
|
||||
func HLS(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("new hls request: %+v\n", r)
|
||||
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
module server
|
||||
|
||||
go 1.23
|
@ -1,33 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
func serveVideo(w http.ResponseWriter, r *http.Request) {
|
||||
filePath := "files/111.mp4"
|
||||
|
||||
// Открытие запрашиваемого файла
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
log.Fatalln("Ошибка открытия файла: ", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
log.Fatalln("Ошибка закрытия файла: ", err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "video/mp4")
|
||||
// Разрешаем частичную загрузку (поддержка перемотки)
|
||||
w.Header().Set("Accept-Ranges", "bytes")
|
||||
|
||||
http.ServeFile(w, r, filePath)
|
||||
}
|
@ -1,584 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"reader/internal/processor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Определение параметров записи
|
||||
var date, startTime, endTime string
|
||||
fmt.Println("Введите дату записи ДД-ММ-ГГГГ:")
|
||||
fmt.Scan(&date)
|
||||
fmt.Println("Введите время начала записи ЧЧ-ММ:")
|
||||
fmt.Scan(&startTime)
|
||||
fmt.Println("Введите время окончания записи ЧЧ-ММ:")
|
||||
fmt.Scan(&endTime)
|
||||
|
||||
// Вычисление времени начала и конца, запрошенного фрагмента
|
||||
startHour, startMinute, endHour, endMinute := processor.CalcNeededTime(startTime, endTime)
|
||||
|
||||
var endMinuteFirstVideo, durationHour int
|
||||
|
||||
// Вычисление длительности (часов) запрошенного фрагмента видеозаписи
|
||||
durationHour, endMinuteFirstVideo =
|
||||
processor.CalcEndMinuteFirstVideo(durationHour, endMinuteFirstVideo, startHour, endHour, endMinute)
|
||||
|
||||
// Определение пути хранения видеозаписей
|
||||
path := "../writer/"
|
||||
|
||||
switch durationHour {
|
||||
case 0:
|
||||
processed, created := processor.CreateFile(
|
||||
startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
processor.MergeMKV(created)
|
||||
processor.DeleteTrimmedFragments(created)
|
||||
|
||||
case 1:
|
||||
processed, created1 := processor.CreateFile(
|
||||
startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
processed, created2 := processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
processor.MergeMKV(created1, created2)
|
||||
processor.DeleteTrimmedFragments(created1, created2)
|
||||
|
||||
case 2:
|
||||
processed, created1 := processor.CreateFile(
|
||||
startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
processed, created2 := processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
processed, created3 := processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
processor.MergeMKV(created1, created2, created3)
|
||||
processor.DeleteTrimmedFragments(created1, created2, created3)
|
||||
|
||||
case 3:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(
|
||||
startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 4)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 2; i++ {
|
||||
processed, created = processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created4 := processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[3] = created4
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 4:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(
|
||||
startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 5)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 3; i++ {
|
||||
processed, created = processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created5 := processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[4] = created5
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 5:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(
|
||||
startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 6)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 4; i++ {
|
||||
processed, created = processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created6 := processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[5] = created6
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 6:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(
|
||||
startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 7)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 5; i++ {
|
||||
processed, created = processor.CreateFile(
|
||||
processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created7 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[6] = created7
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 7:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 8)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 6; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created8 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[7] = created8
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 8:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 9)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 7; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created9 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[8] = created9
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 9:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 10)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 8; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created10 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[9] = created10
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 10:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 11)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 9; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created11 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[10] = created11
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 11:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 12)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 10; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created12 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[11] = created12
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 12:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 13)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 11; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created13 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[12] = created13
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 13:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 14)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 12; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created14 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[13] = created14
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 14:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 15)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 13; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created15 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[14] = created15
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 15:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 16)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 14; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created16 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[15] = created16
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 16:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 17)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 15; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created17 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[16] = created17
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 17:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 18)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 16; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created18 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[17] = created18
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 18:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 19)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 17; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created19 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[18] = created19
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 19:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 20)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 18; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created20 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[19] = created20
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 20:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 21)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 19; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created21 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[20] = created21
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 21:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 22)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 20; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created22 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[21] = created22
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 22:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 23)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 21; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created23 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[22] = created23
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
|
||||
case 23:
|
||||
created := ""
|
||||
|
||||
processed, created1 := processor.CreateFile(startTime, date, path, startMinute, endMinuteFirstVideo, 0)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS := make([]string, 24)
|
||||
createdS[0] = created1
|
||||
|
||||
for i := 1; i <= 22; i++ {
|
||||
processed, created = processor.CreateFile(processed, date, path, startMinute, endMinuteFirstVideo, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[i] = created
|
||||
}
|
||||
|
||||
processed, created24 := processor.CreateFile(processed, date, path, startMinute, endMinute, durationHour)
|
||||
log.Println("Создан файл: ", processed)
|
||||
|
||||
createdS[23] = created24
|
||||
|
||||
processor.MergeMKV(createdS...)
|
||||
processor.DeleteTrimmedFragments(createdS...)
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
module reader
|
||||
|
||||
go 1.23.6
|
@ -1,215 +0,0 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Функция copyFile находит файл в репозитории и создает его копию.
|
||||
func copyFiles(path string, filename []string) (filenameCopied []string, err error) {
|
||||
for i := 0; i < len(filename); i++ {
|
||||
input, err := os.Open(path + filename[i])
|
||||
if err != nil {
|
||||
log.Println("Ошибка открытия input файла: ", err)
|
||||
}
|
||||
defer func() {
|
||||
err = input.Close()
|
||||
if err != nil {
|
||||
log.Println("Ошибка закрытия input файла.")
|
||||
}
|
||||
}()
|
||||
|
||||
output, err := os.Create(time.Now().Format("15-04-05") + "video.mkv")
|
||||
if err != nil {
|
||||
log.Println("Ошибка создания output файла: ", err)
|
||||
}
|
||||
defer func() {
|
||||
err = output.Close()
|
||||
if err != nil {
|
||||
log.Println("Ошибка закрытия output файла.")
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
_, err = io.Copy(output, input)
|
||||
if err != nil {
|
||||
log.Println("Ошибка копирования файла")
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Файлы скопированы.")
|
||||
return filename, err
|
||||
}
|
||||
|
||||
// MergeMKV принимает названия видеофайлов для объединения.
|
||||
func MergeMKV(filenames ...string) {
|
||||
// Создание файла со списком видеофайлов для объединения
|
||||
f, err := os.Create("videoList.txt")
|
||||
if err != nil {
|
||||
log.Fatalln("Ошибка создания файла со списком видеофайлов для объединения", err)
|
||||
}
|
||||
defer func() {
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
log.Fatalln("Ошибка закрытия файла: ", err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
// Запись видеофайлов для объединения
|
||||
n := len(filenames)
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
_, err = f.WriteString("file '" + filenames[i] + "'\n")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = mergeFfmpeg(f)
|
||||
if err != nil {
|
||||
log.Fatalln("Ошибка объединения видеофайлов с помощью ffmpeg: ", err)
|
||||
}
|
||||
|
||||
err = os.Remove("videoList.txt")
|
||||
if err != nil {
|
||||
log.Println("Ошибка удаления временного файла videoList.txt: ", err)
|
||||
}
|
||||
log.Println("Временный файл videoList.txt успешно удален")
|
||||
}
|
||||
|
||||
// DeleteTrimmedFragments удаляет временно созданные файлы.
|
||||
func DeleteTrimmedFragments(filenames ...string) {
|
||||
n := len(filenames)
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
err := os.Remove(filenames[i])
|
||||
if err != nil {
|
||||
log.Printf("Ошибка удаления временного файла %s: %s", filenames[i], err.Error())
|
||||
}
|
||||
log.Printf("Временный файл %s успешно удален", filenames[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Конвертация времени из формата строки в формат чисел
|
||||
func partitionTime(time string) (startHour int, startMinute int, err error) {
|
||||
// Разделение часов и минут
|
||||
s := []byte(time)
|
||||
h := []byte{s[0], s[1]}
|
||||
m := []byte{s[3], s[4]}
|
||||
|
||||
// Преобразование часов и минут в целые числа
|
||||
startHour, err = strconv.Atoi(string(h))
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
startMinute, err = strconv.Atoi(string(m))
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
return startHour, startMinute, nil
|
||||
}
|
||||
|
||||
// Формирование имени файла
|
||||
func createFilename(time, date string) (fileName string) {
|
||||
s := []byte(time)
|
||||
s[3], s[4] = '0', '0'
|
||||
fileName = string(s) + "_" + date + ".mkv"
|
||||
return fileName
|
||||
}
|
||||
|
||||
// Добавление одного часа к строке в формате ЧЧ-ММ
|
||||
func addHour(startTime string) (fileName string) {
|
||||
s := []byte(startTime)
|
||||
if s[0] == '0' && s[1] == '9' {
|
||||
s[0] = '1'
|
||||
s[1] = '0'
|
||||
} else if s[0] == '1' && s[1] == '9' {
|
||||
s[0] = '2'
|
||||
s[1] = '0'
|
||||
} else {
|
||||
s[1]++
|
||||
}
|
||||
fileName = string(s)
|
||||
return fileName
|
||||
}
|
||||
|
||||
// Проверка наличия файла
|
||||
func checkFile(path, fileName string) error {
|
||||
found := false
|
||||
|
||||
err := filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err // Возвращаем ошибку, если возникла
|
||||
}
|
||||
if !info.IsDir() && info.Name() == fileName {
|
||||
log.Println("Файл обнаружен:", filePath)
|
||||
found = true
|
||||
return filepath.SkipDir // Останавливаем обход после нахождения
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
return errors.New("file not found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateFile проверяет запрошенное количество часов записи, проверяет существование видеофайла в репозитории,
|
||||
// отрезает запрашиваемый отрезок файла, возвращает обработанный час записи и название обрезанного файла.
|
||||
//
|
||||
// При значении параметра durationHour > 0, в первом вызове функции необходимо вручную выставить durationHour на 0.
|
||||
func CreateFile(startTime, date, path string, startMinute, endMinute, durationHour int) (
|
||||
startTimeCreatedFile string, outputFile string) {
|
||||
var startM, finishM string
|
||||
|
||||
// Проверка длительности видео
|
||||
if endMinute == 60 || endMinute == 0 {
|
||||
finishM = "01:00:00"
|
||||
} else {
|
||||
finishM = "00:" + strconv.Itoa(endMinute) + ":00"
|
||||
}
|
||||
|
||||
// Проверка запрошенного количества часов записи
|
||||
if durationHour > 0 {
|
||||
startTime = addHour(startTime)
|
||||
startM = "00:00:00"
|
||||
} else {
|
||||
startM = "00:" + strconv.Itoa(startMinute) + ":00"
|
||||
}
|
||||
|
||||
// Проверка существования видеофайла в репозитории
|
||||
filename := createFilename(startTime, date)
|
||||
|
||||
err := checkFile(path, filename)
|
||||
if err != nil {
|
||||
log.Fatalln("Ошибка начального файла: ", err)
|
||||
}
|
||||
|
||||
// Обрезание видеофайла
|
||||
inputFile := path + filename
|
||||
|
||||
if endMinute == 60 {
|
||||
|
||||
}
|
||||
|
||||
outputFile = trimMKV(
|
||||
inputFile,
|
||||
filename,
|
||||
startM,
|
||||
finishM,
|
||||
)
|
||||
|
||||
return startTime, outputFile
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package processor
|
||||
|
||||
import "log"
|
||||
|
||||
// CalcNeededTime принимает начальное и конечное время записи, конвертирует временя из формата строки в формат
|
||||
// числа и возвращает час и минуту начала времени записи, час и минуту конца времени записи.
|
||||
func CalcNeededTime(startTime, endTime string) (startHour, startMinute, endHour, endMinute int) {
|
||||
// Расчет требуемого времени записи
|
||||
startHour, startMinute, err := partitionTime(startTime)
|
||||
if err != nil {
|
||||
log.Fatal("Ошибка конвертации: ", err)
|
||||
}
|
||||
endHour, endMinute, err = partitionTime(endTime)
|
||||
if err != nil {
|
||||
log.Fatal("Ошибка конвертации: ", err)
|
||||
}
|
||||
|
||||
return startHour, startMinute, endHour, endMinute
|
||||
}
|
||||
|
||||
// CalcEndMinuteFirstVideo вычисляет необходимость смены часа (переключение одного фрагмента видеозаписи
|
||||
// (которое длится 1 час) на другой фрагмент видеозаписи) и возвращает количество часов (требуемое количество фрагментов
|
||||
// видеозаписи), длительность минут (объект, отвечающий за показатель минут) каждого фрагмента для формирования итоговой
|
||||
// видеозаписи (кроме последнего видеофрагмента, при условии durationHour > 0 (третий объект, возвращаемый функцией
|
||||
// calcEndMinuteFirstVideo).
|
||||
//
|
||||
// В случае, если необходимо взять полный фрагмент видеофайла, например с 00-00 до 03-00, значениеdurationHour будет
|
||||
//
|
||||
// снижено на 1 и возвращено.
|
||||
func CalcEndMinuteFirstVideo(durationHour, endMinuteFirstVideo, startHour, endHour, endMinute int) (
|
||||
durationHourCalc int, endMinuteFirstVideoCalc int) {
|
||||
durationHour = endHour - startHour
|
||||
|
||||
if durationHour > 0 {
|
||||
endMinuteFirstVideo = 60
|
||||
} else {
|
||||
endMinuteFirstVideo = endMinute
|
||||
}
|
||||
|
||||
if endMinute == 0 && durationHour > 0 {
|
||||
durationHour -= 1
|
||||
}
|
||||
|
||||
return durationHour, endMinuteFirstVideo
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
// trimMKV обрезает видеофайл и возвращает название созданного нового файла.
|
||||
func trimMKV(inputFile, outputFile, startTime, finishTime string) (outputFileTrimmed string) {
|
||||
outputFile = time.Now().Format("15-04-05") + outputFile
|
||||
|
||||
cmd := exec.Command("ffmpeg",
|
||||
"-i", inputFile,
|
||||
"-ss", startTime,
|
||||
"-to", finishTime,
|
||||
"-c", "copy",
|
||||
outputFile)
|
||||
|
||||
err := cmd.Run()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Видео успешно обрезано")
|
||||
return outputFile
|
||||
}
|
||||
|
||||
// mergeFfmpeg объединяет видеофайлы с помощью ffmpeg
|
||||
func mergeFfmpeg(f *os.File) error {
|
||||
cmd := exec.Command("ffmpeg",
|
||||
"-f", "concat",
|
||||
"-safe", "0",
|
||||
"-i", f.Name(),
|
||||
"-c", "copy",
|
||||
time.Now().Format("15-04-05")+"_video.mkv")
|
||||
|
||||
err := cmd.Run()
|
||||
|
||||
if err != nil {
|
||||
log.Println("Ошибка исполнения запроса ffmpeg: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println("Видео успешно объединено")
|
||||
return nil
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user