Привет всем любителям покодить! Хочу поделиться небольшим личным проектом, который родился из чистой бытовой необходимости. Я давно хотел иметь возможность удаленно поглядывать на свою дачу, особенно когда уезжаю на несколько недель. Готовые решения в духе "умных камер" меня не совсем устраивают: то подписки дорогие, то Privacy Policy сомнительная, то функционал избыточный. В итоге я решил, что проще и надежнее будет написать свою собственную утилиту.
Идея проста: поставить на даче маломощный неттоп, подключить к нему обычную веб-камеру, которая будет транслировать видео в интернет, и смотреть трансляцию через телеграм, куда я и так захожу постоянно.
Выбор инструментов пал на два кита: Go и FFmpeg
- Go (Golang) идеально подошел для этой задачи. Мне нужен один бинарный файл, без зависимостей, который можно просто скопировать на неттоп с любой ОС (в моем случае Linux) и запустить.
- FFmpeg - я не стал изобретать велосипед и пытаться работать с камерой напрямую, а просто решил поручить всю работу FFmpeg, вызвав его из моей Go-программы.
Код получился на удивление компактным и читаемым:
package main
import (
"fmt"
"log"
"os/exec"
"runtime"
)
func main() {
// URL RTMP-сервера назначения (в данном случае для Telegram)
rtmpURL := "rtmps://dc4-1.rtmp.t.me/s/КЛЮЧ_ТРАНСЛЯЦИИ"
// Получение имени устройства камеры в зависимости от ОС
device := getCameraDevice()
// Формирование аргументов командной строки для FFmpeg:
args := []string{
"-f", "v4l2", // Формат входного устройства (для Windows: "dshow")
"-video_size", "1280x720",
"-framerate", "30",
"-i", device, // Источник видео
"-c:v", "libx264", // Кодек видео
"-preset", "veryfast", // Настройка скорости кодирования (быстрое)
"-tune", "zerolatency", // Настройка для минимальной задержки
"-pix_fmt", "yuv420p", // Формат пикселей (совместимый с большинством плееров)
"-f", "flv", // Формат выходного контейнера (FLV)
rtmpURL, // URL назначения для трансляции
}
// Создание объекта команды для запуска ffmpeg с подготовленными аргументами
cmd := exec.Command("ffmpeg", args...)
// Перенаправление стандартного вывода и вывода ошибок FFmpeg в лог программы
// Это позволяет видеть диагностические сообщения FFmpeg в консоли
cmd.Stdout = log.Writer()
cmd.Stderr = log.Writer()
// Информационное сообщение о начале трансляции
fmt.Printf("Запуск трансляции на %s\n", rtmpURL)
// Запуск команды FFmpeg и ожидание её завершения
err := cmd.Run()
if err != nil {
// Аварийное завершение программы с выводом ошибки, если трансляция не удалась
log.Fatalf("Ошибка трансляции: %v", err)
}
}
// Функция для определения устройства камеры в зависимости от операционной системы
func getCameraDevice() string {
// Использование runtime.GOOS для определения операционной системы
switch runtime.GOOS {
case "darwin": // macOS
return "default" // Стандартное устройство захвата в macOS
case "linux": // Linux
return "/dev/video0" // Стандартный путь к устройству видеозахвата
case "windows": // Windows
return "video=Integrated Camera" // Имя устройства может отличаться. Пример для встроенной камеры
default: // Другие ОС
return "" // Пустая строка для неизвестных систем
}
}
Как это все работает изнутри
1. Получаем адрес RTMP-сервера Telegram, куда нужно отправлять видео.

Для этого создаем закрытый канал в Telegram, кликаем по значку трансляций, жмем Трансляция с помощью...

копируем ссылку и ключ трансляции, и добавляем ссылку в программу
2. Функция getCameraDevice() определяет операционную систему и в зависимости от нее возвращает путь к камере. Для моего неттопа на Linux это будет /dev/video0.
3. Далее мы формируем команду для FFmpeg, которая говорит ему:
- -f v4l2: Брать видео с устройства видеозахвата (в Linux).
- -video_size 1280x720 -framerate 30: Использовать разрешение 720p и 30 кадров в секунду.
- -i /dev/video0: Смотреть на первую подключенную камеру.
- -c:v libx264 -preset veryfast -tune zerolatency: Закодировать видео в H.264 очень быстро и с минимальной задержкой - это критично для почти live-трансляции.
- -f flv: Упаковать все в контейнер FLV, который идеально подходит для стриминга.
- И отправить получившийся поток по указанному rtmpURL.
Программа запускает FFmpeg как внешний процесс и перенаправляет его логи в свой собственный вывод. Это очень удобно для отладки. Если что-то пойдет не так (например, камера недоступна или неверный URL), мы сразу увидим причину в консоли.
Запустил для проверки на своем ноутбуке, в качестве источника встроенная веб-камера

программа работает без ошибок, далее запускаю трансляцию в своем закрытом Telegram канале

Все отлично! Присутствует небольшая задержка, примерно 2-3 секунды.
Что получилось:
- Одна команда на запуск. Никаких конфигов, лишних библиотек.
- Программа работает неделями без перезапуска. Go-приложение не падает, а если упадет FFmpeg, то программу легко перезапустить через systemd.
- Трансляция потребляет мало ресурсов. На неттопе нагрузка на CPU около 15-20%, что вполне приемлемо.
- Трансляцию можно смотреть прямо в Telegram - на телефоне, ноутбуке, где угодно.
Спасибо за ваше время и внимание! Ваша поддержка очень важна для меня! Если вам понравилась статья, пожалуйста, поставьте лайк этой статье на моем канале Дзен
Подпишитесь на мой Телеграм-канал, чтобы быть в курсе новых статей.
Удачи в программировании!