Как стать автором
Поиск
Написать публикацию
Обновить

Замена YouTube Kids

Уровень сложностиПростой
Время на прочтение5 мин
Количество просмотров1.2K

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

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

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

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

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

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

Теги:
Хабы:
-2
Комментарии8

Публикации

Ближайшие события