216 lines
6.1 KiB
Go
216 lines
6.1 KiB
Go
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
|
||
}
|