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.
Maintainers
Readme
Opex YouTube Search / Поиск Opex YouTube
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:
getVideoandgetPlaylistaccept both YouTube URLs and IDs. - Combined Search:
searchAllfunction 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-infoUsage (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]): ReturnsPromise<Video[]>searchChannels(query, [options]): ReturnsPromise<Channel[]>searchLive(query, [options]): ReturnsPromise<LiveVideo[]>searchAll(query, [options]): ReturnsPromise<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. ReturnsPromise<VideoDetail | null>getPlaylist(playlistIdOrUrl, [options]): Accepts Playlist ID or URL. ReturnsPromise<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
