npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opex-yt-info

v1.0.2

Published

Node.js library for searching YouTube (videos, channels, live), getting video/playlist metadata, and fetching homepage/trending videos.

Readme

npm version License: MIT Visitors

Opex YouTube Search / Поиск Opex YouTube

English | Русский


English

A Node.js library (ESM) providing separate, intuitive functions for searching YouTube content (videos, channels, live streams) and retrieving basic metadata for videos and playlists.

Features

  • Clear Separation: Dedicated functions like searchVideos, searchChannels, searchLive, getVideo, getPlaylist.
  • Promise-based: All functions return Promises for easy async/await usage.
  • Type Definitions: Includes TypeScript definitions for better developer experience.
  • Search Options: Supports common search options like language (hl), region (gl), pagination (pageStart, pageEnd), and User-Agent.
  • URL/ID Flexibility: getVideo and getPlaylist accept both YouTube URLs and IDs.
  • Combined Search: searchAll function to get videos, channels, and live streams in one call.

Installation

npm install opex-yt-info
# or
yarn add opex-yt-info
# or
pnpm add opex-yt-info

Usage (ESM)

import {
  searchVideos,
  searchChannels,
  searchLive,
  searchAll,
  getVideo,
  getPlaylist
} from 'opex-yt-info';

// --- Search Examples ---

async function runSearches() {
  try {
    console.log('--- Searching Videos ---');
    const videos = await searchVideos('lofi hip hop radio', { pageEnd: 1 });
    if (videos.length > 0) {
        videos.slice(0, 3).forEach(v => console.log(`[Video] ${v.title} (${v.timestamp}) - ${v.views} views`));
    } else {
        console.log('No videos found.');
    }


    console.log('\n--- Searching Channels ---');
    const channels = await searchChannels('freecodecamp', { pageEnd: 1 });
     if (channels.length > 0) {
        channels.slice(0, 1).forEach(c => console.log(`[Channel] ${c.name} (${c.subCountLabel})`));
    } else {
        console.log('No channels found.');
    }

    console.log('\n--- Searching Live ---');
    const liveStreams = await searchLive('live news', { pageEnd: 1 });
    if (liveStreams.length > 0) {
        liveStreams.slice(0, 3).forEach(l => console.log(`[Live] ${l.title} (${l.watching} watching)`));
    } else {
        console.log('No live streams found (or none matching "live news" currently).');
    }


     console.log('\n--- Searching All (Videos, Channels, Live, maybe Playlists) ---');
    const allResults = await searchAll('synthwave', { pageEnd: 1 });
     if (allResults.length > 0) {
        allResults.slice(0, 5).forEach(item => {
            const title = item.title || item.name || 'Unknown Title'; // Use name for channel
            console.log(`[All:${item.type}] ${title}`);
        });
    } else {
        console.log('No results found for "synthwave".');
    }

  } catch (error) {
    console.error('Search failed:', error);
  }
}

// --- Get Metadata Examples ---

async function runGetters() {
  try {
    const videoIdOrUrl = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'; // Rick Astley - Never Gonna Give You Up
    console.log(`\n--- Getting Video Info [${videoIdOrUrl}] ---`);
    const video = await getVideo(videoIdOrUrl);
    if (video) {
      console.log(`Title: ${video.title}`);
      console.log(`Views: ${video.views}`);
      console.log(`Upload Date: ${video.uploadDate}`);
      console.log(`Genre: ${video.genre}`);
    } else {
      console.log('Video not found or error fetching.');
    }

    const playlistIdOrUrl = 'PLzDFYTz8KSyBUDaNaPOKVjomV2lCm5W4G'; // Example playlist ID
    console.log(`\n--- Getting Playlist Info [${playlistIdOrUrl}] ---`);
    const playlist = await getPlaylist(playlistIdOrUrl);
     if (playlist) {
      console.log(`Title: ${playlist.title}`);
      console.log(`Video Count: ${playlist.size}`);
      console.log(`Update Date: ${playlist.date}`);
      console.log(`First video: ${playlist.videos[0]?.title} (${playlist.videos[0]?.duration.timestamp})`);
    } else {
      console.log('Playlist not found or error fetching.');
    }

  } catch (error) {
    console.error('Metadata fetch failed:', error);
  }
}


// Run the examples
await runSearches();
await runGetters();

API

(See index.d.ts for detailed TypeScript definitions)

Search Functions

All search functions accept query (string) and optional options (object). Options include: pageStart, pageEnd, hl, gl, category, sp, userAgent.

  • searchVideos(query, [options]): Returns Promise<Video[]>
  • searchChannels(query, [options]): Returns Promise<Channel[]>
  • searchLive(query, [options]): Returns Promise<LiveVideo[]>
  • searchAll(query, [options]): Returns Promise<Array<Video | Channel | LiveVideo | PlaylistSummary>>

Metadata Functions

These functions accept an ID or URL (string) and optional options (object). Options include: hl, gl, userAgent.

  • getVideo(videoIdOrUrl, [options]): Accepts Video ID or URL. Returns Promise<VideoDetail | null>
  • getPlaylist(playlistIdOrUrl, [options]): Accepts Playlist ID or URL. Returns Promise<PlaylistDetail | null>

Returned Object Structures

Video (from search)
{
  type: 'video';
  videoId: string;
  url: string;
  title: string;
  description: string; // May be truncated
  image: string;       // Thumbnail URL
  thumbnail: string;   // Thumbnail URL
  seconds: number;     // Duration in seconds
  timestamp: string;   // Duration formatted (e.g., "3:10")
  duration: { seconds: number; timestamp: string; toString: () => string; };
  ago: string;         // Upload time relative (e.g., "1 year ago")
  views: number;
  author: { name: string; url: string; };
}
Channel (from search)
{
  type: 'channel';
  name: string;
  url: string;
  baseUrl?: string;    // Relative URL path
  id?: string;         // Channel ID (if available)
  title: string;
  about?: string;      // Short description
  image: string;       // Avatar URL
  thumbnail: string;   // Avatar URL
  videoCount: number;
  videoCountLabel: string; // e.g., "1.2K videos"
  verified: boolean;
  subCount: number;    // Approximate subscriber count
  subCountLabel: string; // e.g., "1.2M subscribers"
}
LiveVideo (from search)
{
  type: 'live';
  videoId: string;
  url: string;
  title: string;
  description: string;
  image: string;
  thumbnail: string;
  watching: number;    // Current viewers
  author: { name: string; url: string; };
  status: 'LIVE' | 'UPCOMING';
  startTime?: number;  // Unix timestamp (ms) for upcoming
  startDate?: string;  // Formatted date string for upcoming
}
PlaylistSummary (from searchAll)
{
    type: 'list';
    listId: string;
    url: string;
    title: string;
    thumbnail: string;
    image: string; // Alias
    videoCount: number;
    author: { name: string; url: string; };
}
VideoDetail (from getVideo)

Inherits from Video and adds fields potentially available from the underlying lookup:

{
  // ... all properties from Video ...
  type: 'video';
  genre?: string;
  uploadDate?: string; // e.g., "2023-10-27"
}
PlaylistDetail (from getPlaylist)
{
  title: string;
  listId: string;
  url: string;
  size?: number;       // Video count
  views?: number;      // Playlist views (if available)
  date?: string;       // Last updated date (YYYY-MM-DD) if available
  image?: string;      // Playlist thumbnail URL
  thumbnail?: string;  // Playlist thumbnail URL
  videos: Array<{      // Array of video summaries within the playlist
    title: string;
    videoId: string;
    listId: string;
    thumbnail: string;
    duration: { seconds: number; timestamp: string; toString: () => string; };
    author: { name: string; url: string; };
  }>;
  author: { name: string; url: string; }; // Playlist creator
}

License

MIT


Русский

Node.js библиотека (ESM), предоставляющая отдельные, интуитивно понятные функции для поиска контента YouTube (видео, каналы, трансляции) и получения базовых метаданных для видео и плейлистов.

Возможности

  • Четкое разделение: Выделенные функции, такие как searchVideos, searchChannels, searchLive, getVideo, getPlaylist.
  • На основе Promise: Все функции возвращают Promise для удобного использования с async/await.
  • Определения типов: Включает определения TypeScript для улучшения опыта разработки.
  • Опции поиска: Поддерживает общие опции поиска, такие как язык (hl), регион (gl), пагинация (pageStart, pageEnd) и User-Agent.
  • Гибкость URL/ID: getVideo и getPlaylist принимают как URL YouTube, так и ID.
  • Общий поиск: Функция searchAll для получения видео, каналов и трансляций одним вызовом.

Установка

npm install opex-yt-info
# или
yarn add opex-yt-info
# или
pnpm add opex-yt-info

Использование (ESM)

import {
  searchVideos,
  searchChannels,
  searchLive,
  searchAll,
  getVideo,
  getPlaylist
} from 'opex-yt-info';

// --- Примеры поиска ---

async function runSearches() {
  try {
    console.log('--- Поиск Видео ---');
    const videos = await searchVideos('lofi hip hop radio', { pageEnd: 1 });
     if (videos.length > 0) {
        videos.slice(0, 3).forEach(v => console.log(`[Видео] ${v.title} (${v.timestamp}) - ${v.views} просмотров`));
    } else {
        console.log('Видео не найдены.');
    }

    console.log('\n--- Поиск Каналов ---');
    const channels = await searchChannels('freecodecamp', { pageEnd: 1 });
    if (channels.length > 0) {
        channels.slice(0, 1).forEach(c => console.log(`[Канал] ${c.name} (${c.subCountLabel})`));
    } else {
        console.log('Каналы не найдены.');
    }

    console.log('\n--- Поиск Трансляций ---');
    const liveStreams = await searchLive('live news', { pageEnd: 1 });
    if (liveStreams.length > 0) {
        liveStreams.slice(0, 3).forEach(l => console.log(`[Live] ${l.title} (${l.watching} смотрят)`));
    } else {
        console.log('Трансляции не найдены (или нет совпадений с "live news" в данный момент).');
    }

     console.log('\n--- Поиск Всего (Видео, Каналы, Live, возможно Плейлисты) ---');
    const allResults = await searchAll('synthwave', { pageEnd: 1 });
    if (allResults.length > 0) {
        allResults.slice(0, 5).forEach(item => {
            const title = item.title || item.name || 'Неизвестное название'; // Используем name для канала
            console.log(`[Все:${item.type}] ${title}`);
        });
    } else {
        console.log('Результаты для "synthwave" не найдены.');
    }

  } catch (error) {
    console.error('Поиск не удался:', error);
  }
}

// --- Примеры получения метаданных ---

async function runGetters() {
  try {
    const videoIdOrUrl = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'; // Rick Astley - Never Gonna Give You Up
    console.log(`\n--- Получение информации о видео [${videoIdOrUrl}] ---`);
    const video = await getVideo(videoIdOrUrl);
    if (video) {
      console.log(`Название: ${video.title}`);
      console.log(`Просмотры: ${video.views}`);
      console.log(`Дата загрузки: ${video.uploadDate}`);
      console.log(`Жанр: ${video.genre}`);
    } else {
      console.log('Видео не найдено или ошибка загрузки.');
    }

    const playlistIdOrUrl = 'PLzDFYTz8KSyBUDaNaPOKVjomV2lCm5W4G'; // Пример ID плейлиста
    console.log(`\n--- Получение информации о плейлисте [${playlistIdOrUrl}] ---`);
    const playlist = await getPlaylist(playlistIdOrUrl);
     if (playlist) {
      console.log(`Название: ${playlist.title}`);
      console.log(`Кол-во видео: ${playlist.size}`);
      console.log(`Дата обновления: ${playlist.date}`);
      console.log(`Первое видео: ${playlist.videos[0]?.title} (${playlist.videos[0]?.duration.timestamp})`);
    } else {
      console.log('Плейлист не найден или ошибка загрузки.');
    }

  } catch (error) {
    console.error('Получение метаданных не удалось:', error);
  }
}

// Запуск примеров
await runSearches();
await runGetters();

API

(См. index.d.ts для подробных определений TypeScript)

Функции Поиска

Все функции поиска принимают query (string) и опциональный options (object). Опции включают: pageStart, pageEnd, hl, gl, category, sp, userAgent.

  • searchVideos(query, [options]): Возвращает Promise<Video[]>
  • searchChannels(query, [options]): Возвращает Promise<Channel[]>
  • searchLive(query, [options]): Возвращает Promise<LiveVideo[]>
  • searchAll(query, [options]): Возвращает Promise<Array<Video | Channel | LiveVideo | PlaylistSummary>>

Функции Получения Метаданных

Эти функции принимают ID или URL (string) и опциональный options (object). Опции включают: hl, gl, userAgent.

  • getVideo(videoIdOrUrl, [options]): Принимает ID или URL видео. Возвращает Promise<VideoDetail | null>
  • getPlaylist(playlistIdOrUrl, [options]): Принимает ID или URL плейлиста. Возвращает Promise<PlaylistDetail | null>

Структуры Возвращаемых Объектов

Video (из поиска)
{
  type: 'video';
  videoId: string;
  url: string;
  title: string;
  description: string; // Может быть усеченным
  image: string;       // URL превью
  thumbnail: string;   // URL превью
  seconds: number;     // Длительность в секундах
  timestamp: string;   // Длительность в формате "Ч:ММ:СС"
  duration: { seconds: number; timestamp: string; toString: () => string; };
  ago: string;         // Как давно загружено (напр., "1 год назад")
  views: number;
  author: { name: string; url: string; };
}
Channel (из поиска)
{
  type: 'channel';
  name: string;
  url: string;
  baseUrl?: string;    // Относительный URL
  id?: string;         // ID канала
  title: string;
  about?: string;      // Краткое описание
  image: string;       // URL аватара
  thumbnail: string;   // URL аватара
  videoCount: number;
  videoCountLabel: string; // напр., "1.2K видео"
  verified: boolean;
  subCount: number;    // Примерное кол-во подписчиков
  subCountLabel: string; // напр., "1.2M подписчиков"
}
LiveVideo (из поиска)
{
  type: 'live';
  videoId: string;
  url: string;
  title: string;
  description: string;
  image: string;
  thumbnail: string;
  watching: number;    // Зрителей сейчас
  author: { name: string; url: string; };
  status: 'LIVE' | 'UPCOMING';
  startTime?: number;  // Unix timestamp (ms) для предстоящих
  startDate?: string;  // Форматированная дата для предстоящих
}
PlaylistSummary (из searchAll)
{
    type: 'list';
    listId: string;
    url: string;
    title: string;
    thumbnail: string;
    image: string; // Alias
    videoCount: number;
    author: { name: string; url: string; };
}
VideoDetail (из getVideo)

Наследует от Video и добавляет поля, потенциально доступные при запросе по ID:

{
  // ... все поля из Video ...
  type: 'video';
  genre?: string;
  uploadDate?: string; // напр., "2023-10-27"
}
PlaylistDetail (из getPlaylist)
{
  title: string;
  listId: string;
  url: string;
  size?: number;       // Кол-во видео
  views?: number;      // Просмотры плейлиста (если есть)
  date?: string;       // Дата последнего обновления (YYYY-MM-DD) если есть
  image?: string;      // URL превью плейлиста
  thumbnail?: string;  // URL превью плейлиста
  videos: Array<{      // Массив кратких данных о видео в плейлисте
    title: string;
    videoId: string;
    listId: string;
    thumbnail: string;
    duration: { seconds: number; timestamp: string; toString: () => string; };
    author: { name: string; url: string; };
  }>;
  author: { name: string; url: string; }; // Создатель плейлиста
}

Лицензия

MIT