Skip to content

Commit fccaa93

Browse files
committed
Supports any URL that yt-dlp can handle
1 parent 7832dca commit fccaa93

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

src/services/media.ts

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { TwitchStream, MediaSource } from '../types/index.js';
33
import config from "../config.js";
44
import logger from '../utils/logger.js';
55
import { Youtube } from '../utils/youtube.js';
6-
import { downloadToTempFile } from '../utils/yt-dlp.js';
6+
import ytdl, { downloadToTempFile } from '../utils/yt-dlp.js';
77
import { GeneralUtils } from '../utils/shared.js';
8+
import { YTResponse } from '../types/index.js';
89
import path from 'path';
910

1011
export class MediaService {
@@ -118,7 +119,48 @@ export class MediaService {
118119
};
119120
}
120121

121-
private _resolveDirectUrlSource(url: string): MediaSource {
122+
private async _resolveDirectUrlSource(url: string): Promise<MediaSource> {
123+
// First try to get metadata using yt-dlp
124+
try {
125+
const metadata = await ytdl(url, {
126+
dumpJson: true,
127+
skipDownload: true,
128+
noWarnings: true,
129+
quiet: true
130+
}) as YTResponse;
131+
132+
// If yt-dlp succeeds, use the extracted metadata
133+
if (metadata && metadata.title) {
134+
// Get the best available format URL
135+
let streamUrl = url;
136+
if (metadata.formats && Array.isArray(metadata.formats) && metadata.formats.length > 0) {
137+
// Find the format with both audio and video, preferring higher quality
138+
const bestFormat = metadata.formats
139+
.filter((format) => format.url && format.ext !== 'm3u8') // Avoid HLS streams
140+
.sort((a, b) => {
141+
// Prefer formats with both audio and video
142+
const aScore = (a.vcodec && a.vcodec !== 'none' ? 1 : 0) + (a.acodec && a.acodec !== 'none' ? 1 : 0) + (a.height || 0) / 1000;
143+
const bScore = (b.vcodec && b.vcodec !== 'none' ? 1 : 0) + (b.acodec && b.acodec !== 'none' ? 1 : 0) + (b.height || 0) / 1000;
144+
return bScore - aScore;
145+
})[0];
146+
147+
if (bestFormat && bestFormat.url) {
148+
streamUrl = bestFormat.url;
149+
}
150+
}
151+
152+
return {
153+
url: streamUrl,
154+
title: metadata.title,
155+
type: 'url'
156+
};
157+
}
158+
} catch (error) {
159+
// yt-dlp failed, log debug info and continue to fallback
160+
logger.debug("yt-dlp failed to extract metadata for URL:", url, error);
161+
}
162+
163+
// Fallback to original URL parsing logic
122164
let title = "Direct URL";
123165
try {
124166
const urlObj = new URL(url);

0 commit comments

Comments
 (0)