@ziplayer/plugin 0.1.2 → 0.1.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,45 @@
1
+ export interface SabrPlaybackOptions {
2
+ preferWebM?: boolean;
3
+ preferOpus?: boolean;
4
+ videoQuality?: string;
5
+ audioQuality?: string;
6
+ enabledTrackTypes?: any;
7
+ }
8
+
9
+ export interface StreamResult {
10
+ videoStream: ReadableStream;
11
+ audioStream: ReadableStream;
12
+ selectedFormats: {
13
+ videoFormat: any;
14
+ audioFormat: any;
15
+ };
16
+ videoTitle: string;
17
+ }
18
+
19
+ declare module "googlevideo/sabr-stream" {
20
+ export interface SabrPlaybackOptions {
21
+ preferWebM?: boolean;
22
+ preferOpus?: boolean;
23
+ videoQuality?: string;
24
+ audioQuality?: string;
25
+ enabledTrackTypes?: any;
26
+ }
27
+
28
+ export interface StreamResult {
29
+ videoStream: ReadableStream;
30
+ audioStream: ReadableStream;
31
+ selectedFormats: {
32
+ videoFormat: any;
33
+ audioFormat: any;
34
+ };
35
+ videoTitle: string;
36
+ }
37
+
38
+ export function createSabrStream(videoId: string, options: SabrPlaybackOptions): Promise<{ streamResults: StreamResult }>;
39
+ }
40
+
41
+ declare module "googlevideo/utils" {
42
+ export enum EnabledTrackTypes {
43
+ VIDEO_AND_AUDIO = "VIDEO_AND_AUDIO",
44
+ }
45
+ }
@@ -0,0 +1,96 @@
1
+ import { createWriteStream } from "fs";
2
+ import { join } from "path";
3
+ import { tmpdir } from "os";
4
+
5
+ // Import type declarations
6
+ import type { SabrPlaybackOptions, StreamResult } from "../types/googlevideo";
7
+
8
+ // Re-export types for external use
9
+ export type { StreamResult, SabrPlaybackOptions };
10
+
11
+ export interface OutputStream {
12
+ stream: NodeJS.WritableStream;
13
+ filePath: string;
14
+ }
15
+
16
+ /**
17
+ * Creates a sabr stream for YouTube video download
18
+ */
19
+ export async function createSabrStream(videoId: string, options: SabrPlaybackOptions): Promise<{ streamResults: StreamResult }> {
20
+ try {
21
+ // Dynamic import to avoid build-time errors
22
+ const sabrModule = require("googlevideo/sabr-stream") as any;
23
+ const createSabrStreamImpl = sabrModule.createSabrStream;
24
+
25
+ const streamResults = await createSabrStreamImpl(videoId, options);
26
+
27
+ return { streamResults };
28
+ } catch (error) {
29
+ // Fallback implementation if sabr download is not available
30
+ throw new Error(`Sabr download not available: ${error}`);
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Creates an output stream for writing downloaded content
36
+ */
37
+ export function createOutputStream(videoTitle: string, mimeType: string): OutputStream {
38
+ const sanitizedTitle = videoTitle.replace(/[<>:"/\\|?*]/g, "_").substring(0, 100);
39
+ const extension = getExtensionFromMimeType(mimeType);
40
+ const fileName = `${sanitizedTitle}.${extension}`;
41
+ const filePath = join(tmpdir(), fileName);
42
+
43
+ const stream = createWriteStream(filePath);
44
+
45
+ return {
46
+ stream,
47
+ filePath,
48
+ };
49
+ }
50
+
51
+ /**
52
+ * Creates a stream sink for piping data with progress tracking
53
+ */
54
+ export function createStreamSink(format: any, outputStream: NodeJS.WritableStream, progressBar: any) {
55
+ return new WritableStream({
56
+ start() {
57
+ // Initialize progress tracking
58
+ },
59
+ write(chunk) {
60
+ outputStream.write(chunk);
61
+ if (progressBar) {
62
+ progressBar.increment(chunk.length);
63
+ }
64
+ },
65
+ close() {
66
+ outputStream.end();
67
+ },
68
+ });
69
+ }
70
+
71
+ /**
72
+ * Gets file extension from MIME type
73
+ */
74
+ function getExtensionFromMimeType(mimeType: string): string {
75
+ const mimeMap: { [key: string]: string } = {
76
+ "audio/mp4": "m4a",
77
+ "audio/webm": "webm",
78
+ "audio/ogg": "ogg",
79
+ "video/mp4": "mp4",
80
+ "video/webm": "webm",
81
+ "video/ogg": "ogv",
82
+ };
83
+
84
+ return mimeMap[mimeType] || "bin";
85
+ }
86
+
87
+ /**
88
+ * Default sabr playback options
89
+ */
90
+ export const DEFAULT_SABR_OPTIONS: SabrPlaybackOptions = {
91
+ preferWebM: true,
92
+ preferOpus: true,
93
+ videoQuality: "720p",
94
+ audioQuality: "AUDIO_QUALITY_MEDIUM",
95
+ enabledTrackTypes: "VIDEO_AND_AUDIO",
96
+ };
@@ -0,0 +1,87 @@
1
+ import { Readable } from "stream";
2
+
3
+ /**
4
+ * Converts a Web ReadableStream to a Node.js Readable stream
5
+ */
6
+ export function webStreamToNodeStream(webStream: ReadableStream): Readable {
7
+ console.log("🔄 webStreamToNodeStream: Starting conversion");
8
+
9
+ const nodeStream = new Readable({
10
+ read() {
11
+ // This will be handled by the Web Stream reader
12
+ },
13
+ });
14
+
15
+ // Create a reader from the Web Stream
16
+ const reader = webStream.getReader();
17
+ console.log("🔄 webStreamToNodeStream: Got reader");
18
+
19
+ // Read chunks and push to Node.js stream
20
+ const pump = async () => {
21
+ try {
22
+ console.log("🔄 webStreamToNodeStream: Starting pump");
23
+ while (true) {
24
+ const { done, value } = await reader.read();
25
+ if (done) {
26
+ console.log("🔄 webStreamToNodeStream: Stream ended");
27
+ nodeStream.push(null); // End the stream
28
+ break;
29
+ }
30
+ console.log(`🔄 webStreamToNodeStream: Pushing chunk of ${value.length} bytes`);
31
+ nodeStream.push(Buffer.from(value));
32
+ }
33
+ } catch (error) {
34
+ console.error("🔄 webStreamToNodeStream: Error in pump:", error);
35
+ nodeStream.destroy(error as Error);
36
+ }
37
+ };
38
+
39
+ // Start pumping data
40
+ pump();
41
+
42
+ console.log("🔄 webStreamToNodeStream: Conversion complete, returning Node.js stream");
43
+ return nodeStream;
44
+ }
45
+
46
+ /**
47
+ * Converts a Web ReadableStream to a Node.js Readable stream with progress tracking
48
+ */
49
+ export function webStreamToNodeStreamWithProgress(
50
+ webStream: ReadableStream,
51
+ progressCallback?: (bytesRead: number) => void,
52
+ ): Readable {
53
+ const nodeStream = new Readable({
54
+ read() {
55
+ // This will be handled by the Web Stream reader
56
+ },
57
+ });
58
+
59
+ let bytesRead = 0;
60
+ const reader = webStream.getReader();
61
+
62
+ const pump = async () => {
63
+ try {
64
+ while (true) {
65
+ const { done, value } = await reader.read();
66
+ if (done) {
67
+ nodeStream.push(null); // End the stream
68
+ break;
69
+ }
70
+
71
+ const buffer = Buffer.from(value);
72
+ nodeStream.push(buffer);
73
+
74
+ bytesRead += buffer.length;
75
+ if (progressCallback) {
76
+ progressCallback(bytesRead);
77
+ }
78
+ }
79
+ } catch (error) {
80
+ nodeStream.destroy(error as Error);
81
+ }
82
+ };
83
+
84
+ pump();
85
+
86
+ return nodeStream;
87
+ }
package/tsconfig.json CHANGED
@@ -18,6 +18,6 @@
18
18
  "emitDecoratorMetadata": true,
19
19
  "resolveJsonModule": true
20
20
  },
21
- "include": ["src/*"],
21
+ "include": ["src/*", "src/types/*"],
22
22
  "exclude": ["node_modules", "dist", "examples"]
23
23
  }