Проблема с повреждением видеофайлов, записанных с использованием OpenCV, может быть связана с несколькими факторами.
### Возможные проблемы и их решения:
1. **Неправильное завершение записи**: В OpenCV важно корректно завершить запись, вызвав метод `release()` для объекта `VideoWriter`, иначе файл может быть поврежден. Убедитесь, что этот метод вызывается при выключении записи.
2. **Закрытие видеопотока**: Часто существует некорректное управление объектом `VideoCapture`. Если вы начинаете запись через `VideoCapture` в функции `callback()`, не забудьте закрыть его, когда запись завершена. Можно использовать `cap.release()` для этого.
3. **Формат и кодек**: Убедитесь, что выбранный вами кодек поддерживает режим записи, который вы используете (изменение `fourcc` может помочь). Например, попробуйте использовать `cv2.VideoWriter_fourcc(*'XVID')` или `cv2.VideoWriter_fourcc(*'MJPG')`.
### Реализация кнопки включения/выключения записи
В приведенном вами коде при каждом вызове функции `callback()` объект `cap` создается заново, и это может вызвать проблемы с синхронизацией. Лучше всего инициализировать `cap` один раз глобально и использовать его для записи.
Пример исправленного кода:
```python
import cv2
class Config:
IS_REC = False
OUTPUT = None
config = Config()
cap = cv2.VideoCapture(0)
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
def callback():
if not config.IS_REC:
print("[INFO] Запись начата")
config.IS_REC = True
config.OUTPUT = cv2.VideoWriter(f'videos/g.mp4', fourcc, 30, (width, height), isColor=True)
else:
print(f"[INFO] Запись закончена. Файл сохранился в папку videos")
config.IS_REC = False
config.OUTPUT.release()
config.OUTPUT = None
while True:
ret, frame = cap.read()
if not ret:
break
if config.IS_REC:
config.OUTPUT.write(frame)
cv2.imshow('frame', frame)
# Здесь добавьте вашу логику для обработки нажатия клавиш для вызова callback()
key = cv2.waitKey(1) & 0xFF
if key == ord('r'): # например, 'r' для начала/остановки записи
callback()
elif key == ord('q'): # 'q' для выхода
break
# Освобождение ресурсов
cap.release()
if config.OUTPUT is not None:
config.OUTPUT.release()
cv2.destroyAllWindows()
```
### Обратите внимание:
- **Одна переменная `cap`**: Теперь объект `VideoCapture` создается один раз вне функции `callback()`.
- **Глобальные настройки**: Изменение состояния записи теперь больше не требует повторной инициализации видеопотока.
- **Обработка нажатий клавиш**: Добавлен простой механизм для управления записью через нажатия клавиш. Вы можете настроить это по своему усмотрению.
Эти изменения помогут вам избежать повреждения выходного видеофайла и упростят управление записью.