
Что делать, когда твой ребёнок признаёт только это приложение? Вот не хочет пользоваться аналогами, и всё тут! Как убрать недостатки в такой ситуации и добавить достоинств? Об этом и поговорим.
Какие недостатки YouTube Kids я хотел бы убрать?
Невозможно сделать раздачу исключительно русскоязычной. Это может быть особенно плохо, например, для детей с аутизмом, у которых спец-интерес после просмотра мультиков может проявиться в английском (или любом другом) языке, с нежеланием говорить по-русски.
Невозможность ограничить доступ к любым мультфильмам, кроме заданного списка.
«Замедление» работы сервиса в России. Этот пункт обсуждать я не буду.
Казалось бы, можно было бы пользоваться аналогичными сервисами. Но их авторы вместо того, чтобы скопировать в точности интерфейс предшественника, почему-то решают проявить творческие способности там, где они не требуется. И в результате хороший интерфейс превращается в камень преткновения: некоторые дети отказываются им пользоваться.
Передо мной встала задача сделать что-то, что:
Выглядит идентично YouTube Kids;
Позволяет задать список видео, которые разрешены к просмотру.
Самым простым вариантом мне представился html + js. И вот что вышло после различных экспериментов.
Файл index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="mobile-web-app-capable" content="yes">
<link rel="manifest" href="/manifest.json">
<title>Моя галерея видео</title>
<style>
body {
margin: 0;
display: flex;
flex-direction: column;
height: 100vh;
}
#video-player {
flex: 1;
display: none;
}
#video-player iframe {
width: 100%;
height: 100%;
}
#video-thumbnails {
display: flex;
overflow-x: auto;
padding: 10px;
background: #333;
}
#video-thumbnails img {
height: 100px;
margin-right: 5px;
cursor: pointer;
border: 2px solid transparent;
transition: border-color 0.3s;
}
#video-thumbnails img:hover {
border-color: #fff;
}
iframe {
pointer-events: none;
}
</style>
</head>
<body>
<div id="video-player"></div>
<div id="video-thumbnails"></div>
<script src="script.js"></script>
</body>
</html>
Файл script.js:
// Многострочная строка для хранения VIDEO_ID
const videoList = `
UtXrr8VsbA8
7VPTOfnmiCU
G42s0gshcqY
tgmRf1RPml0
ywWyiGHj5as
P0enXHMINTk
PNQt6bu2MtE
vyFqU1ekEBA
7IbVmn-mIjI
L3LEdwnHKdk
E18TnWNueBs
9_qY5ngjYYs
zn-WjcBSCyA
USCLdqEsXIw
sf2k0vkE7RM
BlAmuUrvMYk
`;
// Разбиваем строку на массив VIDEO_ID
let videoIDs = videoList.trim().split('\n');
// Функция для перемешивания массива (Алгоритм Фишера-Йетса)
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// Перемешиваем список VIDEO_ID
videoIDs = shuffleArray(videoIDs);
// Время скрытия панели (в миллисекундах)
const HIDE_TIMEOUT_MS = 5000;
let hideThumbnailsTimeout; // Таймер для скрытия панели
// Инициализация галереи
function initializeGallery() {
const thumbnailsContainer = document.getElementById('video-thumbnails');
const videoPlayerContainer = document.getElementById('video-player');
// Создаём миниатюры для каждого видео
videoIDs.forEach(videoID => {
const img = document.createElement('img');
img.src = `https://img.youtube.com/vi/${videoID}/hqdefault.jpg`;
img.alt = `Video ${videoID}`;
img.addEventListener('click', () => playVideo(videoID, true)); // Включаем автозапуск для кликов
thumbnailsContainer.appendChild(img);
});
// Открываем первый ролик (не на паузе)
playVideo(videoIDs[0], true);
// Обработчики событий для показа панели
videoPlayerContainer.addEventListener('click', showThumbnails);
videoPlayerContainer.addEventListener('mousemove', showThumbnails);
videoPlayerContainer.addEventListener('touchstart', showThumbnails);
videoPlayerContainer.addEventListener('touchend', showThumbnails);
// Также добавим обработку для pointer-событий (универсальный подход)
videoPlayerContainer.addEventListener('pointerdown', showThumbnails);
videoPlayerContainer.addEventListener('pointerup', showThumbnails);
videoPlayerContainer.addEventListener('pointermove', showThumbnails);
document.body.addEventListener('mousemove', showThumbnails, true); // true указывает на захват события на этапе capture
document.body.addEventListener('click', showThumbnails, true);
function playVideo(videoID, autoplay = true) {
// Генерируем параметры для iframe
const autoplayParam = autoplay ? 1 : 0;
videoPlayerContainer.innerHTML = `
<iframe
src="https://www.youtube.com/embed/${videoID}?autoplay=${autoplayParam}"
frameborder="0"
allowfullscreen>
</iframe>`;
// Показываем видео-плеер
videoPlayerContainer.style.display = 'block';
// Скрываем миниатюры через HIDE_TIMEOUT_MS
resetThumbnailsHideTimer();
}
function resetThumbnailsHideTimer() {
// Если таймер уже установлен, очищаем его
if (hideThumbnailsTimeout) {
clearTimeout(hideThumbnailsTimeout);
}
// Устанавливаем новый таймер для скрытия панели
hideThumbnailsTimeout = setTimeout(() => {
thumbnailsContainer.style.display = 'none';
}, HIDE_TIMEOUT_MS);
}
function showThumbnails(event) {
event.preventDefault(); // Для предотвращения прокрутки на мобильных устройствах
// Показываем панель
thumbnailsContainer.style.display = 'flex';
// Сбрасываем таймер, чтобы панель не исчезла мгновенно
resetThumbnailsHideTimer();
}
}
// Запуск функции инициализации
initializeGallery();
// Функция для перехода в полноэкранный режим
function goFullScreen() {
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen();
} else if (document.documentElement.mozRequestFullScreen) { // Firefox
document.documentElement.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullscreen) { // Chrome, Safari, Opera
document.documentElement.webkitRequestFullscreen();
} else if (document.documentElement.msRequestFullscreen) { // IE/Edge
document.documentElement.msRequestFullscreen();
}
}
// Вызов функции для перехода в полноэкранный режим
goFullScreen();
Пояснения:
В файле script.js вместо строк, начинающихся с UtXrr8VsbA8, вписываете аналогичные коды видеороликов с youtube.com (из адресной строки).
Либо сохраняете оба файла локально на телефон, либо закачиваете их на любой хостинг.
Открываете index.html и наслаждаетесь результатом. В Хроме проще всего создать иконку с этой страничкой сразу на экране телефона (Меню – Добавить на гл. экран).
Так я и сделал, но насладиться до конца не смог – мешала верхняя панель браузера. Убрать ее у меня не получилось, поэтому пришлось применять тяжёлую артиллерию: делать WebView приложение для Андроида, которое будет показывать только эту страницу.
Для этого мне понадобились Android Studio и ChatGPT. Вот примерная последовательность промптов:
Ты – программист на Android с большим опытом. Я хочу создать WebView приложение, чтобы единственной его функцией было показ странички http://мойСайт.ru на полный экран, учитывая следующие требования:
· Приложение должно быть написано в Android Studio на языке Kotlin
· Ориентация приложения должна быть только горизонтальной, без возможности изменения
· Должно быть разрешено автопроигрывание видео на YouTube в настройках приложения
Напиши подробную инструкцию, как написать это приложение.
Напиши, как в качестве иконки приложения сделать фото моего ребенка.
Напиши, как запустить приложение.
Напиши, как создать APK файл и установить его на телефон.
Возможно, всё не пройдет гладко и придётся сделать новые запросы для исправления появившихся ошибок. Но в итоге приложение будет на телефоне:

Также возможно, что я изобрёл велосипед :-)
Но всё же надеюсь, что для кого-то статья оказалась полезной.