diff --git a/src/index.ts b/src/index.ts index a6dbe80..b19b158 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import * as childProcess from 'child_process'; +import { spawnSync } from 'child_process'; import { unlinkSync, readFileSync } from 'fs'; export enum VideoType { @@ -9,7 +9,6 @@ interface ClipVideoBaseParams { url: string, start: number | string, end: number | string, - ffmpegExecutablePath?: string; } interface ClipYouTubeVideoParams extends ClipVideoBaseParams { @@ -24,12 +23,16 @@ const clipYouTubeVideo = (params: ClipYouTubeVideoParams) => { if (!params.downloaderExecutablePath) { throw new Error('Downloader not found.'); } - if (!params.ffmpegExecutablePath) { - throw new Error('ffmpeg not found.'); - } - childProcess.spawnSync(params.downloaderExecutablePath, [params.url, '-o', 'input.webm']); - childProcess.spawnSync(params.ffmpegExecutablePath, ['-ss', params.start.toString(), '-t', params.end.toString(), '-i', 'input.webm', 'output.webm']); - unlinkSync('input.webm'); + spawnSync( + params.downloaderExecutablePath, + [ + '--postprocessor-args', + `-ss ${params.start.toString()} -to ${params.end.toString()}`, + '-o', + 'output.webm', + params.url, + ], + ); const output = readFileSync('output.webm'); unlinkSync('output.webm'); return output; @@ -38,13 +41,13 @@ const clipYouTubeVideo = (params: ClipYouTubeVideoParams) => { export const clipVideo = (params: ClipVideoParams) => { const { type: videoType, url, start, end, + downloaderExecutablePath, } = params; switch (videoType as string) { case VideoType.YOUTUBE: return clipYouTubeVideo({ - ffmpegExecutablePath: process.env.FFMPEG_EXECUTABLE_PATH, - downloaderExecutablePath: process.env.YOUTUBE_DOWNLOADER_EXECUTABLE_PATH, + downloaderExecutablePath, url, start, end, diff --git a/test/index.test.ts b/test/index.test.ts index 5bd946c..645bf3f 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,22 +1,57 @@ import { - describe, it, expect, vi, + describe, it, expect, vi, beforeEach, Mock, } from 'vitest'; -import * as childProcess from 'child_process'; +import { spawnSync } from 'child_process'; +import { readFileSync, unlinkSync } from 'fs'; import * as youtubeClipCore from '../src'; vi.mock('child_process', () => ({ spawnSync: vi.fn(), })); +vi.mock('fs', () => ({ + readFileSync: vi.fn(), + unlinkSync: vi.fn(), +})); + describe('clipVideo', () => { - it('works', () => { + beforeEach(() => { + (readFileSync as Mock).mockReturnValueOnce(Buffer.from('')); + }); + + it('calls the downloader function', () => { + youtubeClipCore.clipVideo({ + downloaderExecutablePath: 'yt-dlp', + type: youtubeClipCore.VideoType.YOUTUBE, + url: 'https://www.youtube.com/watch?v=BaW_jenozKc', + start: 0, + end: 0, + }); + + expect(spawnSync).toBeCalledWith('yt-dlp', expect.anything()); + }); + + it('calls the buffer extract function', () => { + youtubeClipCore.clipVideo({ + downloaderExecutablePath: 'yt-dlp', + type: youtubeClipCore.VideoType.YOUTUBE, + url: 'https://www.youtube.com/watch?v=BaW_jenozKc', + start: 0, + end: 0, + }); + + expect(readFileSync).toBeCalled(); + }); + + it('calls the cleanup function', () => { youtubeClipCore.clipVideo({ + downloaderExecutablePath: 'yt-dlp', type: youtubeClipCore.VideoType.YOUTUBE, url: 'https://www.youtube.com/watch?v=BaW_jenozKc', start: 0, end: 0, }); - expect(childProcess.spawnSync).toBeCalledTimes(2); + expect(unlinkSync).toBeCalled(); }); }); diff --git a/test/try-service.js b/test/try-service.js index d3b8521..a8cc111 100644 --- a/test/try-service.js +++ b/test/try-service.js @@ -1,7 +1,11 @@ const { clipVideo, VideoType } = require('../dist/cjs/development'); const fs = require('fs'); +const dotenv = require('dotenv'); + +dotenv.config(); const clippedVideoBuffer = clipVideo({ + downloaderExecutablePath: process.env.YOUTUBE_DOWNLOADER_EXECUTABLE_PATH, type: VideoType.YOUTUBE, url: 'https://www.youtube.com/watch?v=BaW_jenozKc', start: 0,