瀏覽代碼

Update implementation

Remove ffmpeg hard dependency.
master
TheoryOfNekomata 1 年之前
父節點
當前提交
cec04ba2b1
共有 3 個文件被更改,包括 56 次插入14 次删除
  1. +13
    -10
      src/index.ts
  2. +39
    -4
      test/index.test.ts
  3. +4
    -0
      test/try-service.js

+ 13
- 10
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,


+ 39
- 4
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();
});
});

+ 4
- 0
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,


Loading…
取消
儲存