Замена YouTube Kids

от автора

Что делать, когда твой ребёнок признаёт только это приложение? Вот не хочет пользоваться аналогами, и всё тут! Как убрать недостатки в такой ситуации и добавить достоинств? Об этом и поговорим.

Какие недостатки 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 файл и установить его на телефон.

Возможно, всё не пройдет гладко и придётся сделать новые запросы для исправления появившихся ошибок. Но в итоге приложение будет на телефоне:

Вот так в итоге это выглядит

Вот так в итоге это выглядит

Также возможно, что я изобрёл велосипед 🙂

Но всё же надеюсь, что для кого-то статья оказалась полезной.


ссылка на оригинал статьи https://habr.com/ru/articles/936560/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *