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.
-
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
andgetPlaylist
accept both YouTube URLs and IDs. -
Combined Search:
searchAll
function to get videos, channels, and live streams in one call.
npm install opex-yt-info
# or
yarn add opex-yt-info
# or
pnpm add opex-yt-info
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();
(See index.d.ts
for detailed TypeScript definitions)
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>>
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>
{
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; };
}
{
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"
}
{
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
}
{
type: 'list';
listId: string;
url: string;
title: string;
thumbnail: string;
image: string; // Alias
videoCount: number;
author: { name: string; url: string; };
}
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"
}
{
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
}
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
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();
(См. 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>
{
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; };
}
{
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 подписчиков"
}
{
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; // Форматированная дата для предстоящих
}
{
type: 'list';
listId: string;
url: string;
title: string;
thumbnail: string;
image: string; // Alias
videoCount: number;
author: { name: string; url: string; };
}
Наследует от Video
и добавляет поля, потенциально доступные при запросе по ID:
{
// ... все поля из Video ...
type: 'video';
genre?: string;
uploadDate?: string; // напр., "2023-10-27"
}
{
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