whatever, let's vibe coding
parent
b6065abbac
commit
445b8171a6
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
description: A description of your rule
|
||||
---
|
||||
|
||||
Your rule content
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
import {spawn} from 'child_process';
|
||||
import {readdir} from 'fs/promises';
|
||||
import {createInterface} from 'node:readline';
|
||||
import {runInBackground} from '../lib/ai-generated.ts';
|
||||
import { extname } from 'node:path';
|
||||
|
||||
|
||||
function formatTime(seconds: number): string {
|
||||
|
|
@ -39,9 +41,10 @@ async function getDuration(inputFile: string): Promise<number> {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
async function compressVideo(inputFile: string, outputFile: string) {
|
||||
const duration = await getDuration(inputFile);
|
||||
return new Promise<void>(resolve => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
try {
|
||||
const ffmpeg = spawn('ffmpeg', [
|
||||
'-hwaccel', 'cuda',
|
||||
|
|
@ -93,10 +96,11 @@ async function compressVideo(inputFile: string, outputFile: string) {
|
|||
console.log(); // Новая строка в конце
|
||||
if (code === 0) {
|
||||
console.log(`✅ Completed: ${outputFile}`);
|
||||
resolve();
|
||||
} else {
|
||||
console.error(`❌ Failed with code ${code}`);
|
||||
reject();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
|
||||
ffmpeg.stderr.on('data', (data) => {
|
||||
|
|
@ -109,13 +113,17 @@ async function compressVideo(inputFile: string, outputFile: string) {
|
|||
});
|
||||
}
|
||||
|
||||
const files = await readdir('.');
|
||||
const mp4Files = files.filter(file => file.match(/^VID_.*\.mp4$/));
|
||||
const filesCount = mp4Files.length;
|
||||
const files = (await readdir('.')).filter(name => {
|
||||
return (!name.startsWith('HEVC') && ['mp4', 'mov'].includes(extname(name).toLowerCase().slice(1)))
|
||||
});
|
||||
let filesCount = files.length;
|
||||
|
||||
for (let i = 0; i < filesCount; i++){
|
||||
const file = mp4Files[i];
|
||||
const outputFile = `HEVC_${file.slice(4)}`;
|
||||
const file = files[i];
|
||||
|
||||
// const outputFile = `HEVC_${file.slice(4)}`;
|
||||
const outputFile = `HEVC_${file}`;
|
||||
console.log(`\nProcessing: ${file} [${i + 1}/${filesCount}]`);
|
||||
await compressVideo(file, outputFile);
|
||||
// runInBackground('identity', [file, outputFile])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import { Ollama } from 'ollama';
|
||||
import {getStdin} from '../lib/ai-generated.ts';
|
||||
|
||||
const ollama = new Ollama({ host: 'http://127.0.0.1:11434' });
|
||||
const model = 'gemma3:12b';
|
||||
// const model = 'codellama:13b';
|
||||
// const model = 'aya:8b';
|
||||
|
||||
|
||||
async function streamChat() {
|
||||
let [,,message] = process.argv;
|
||||
if (!message) return;
|
||||
const file = getStdin();
|
||||
const stream = await ollama.chat({
|
||||
model,
|
||||
messages: [
|
||||
{ role: 'user', content: `${message}\n${file}`},
|
||||
],
|
||||
stream: true,
|
||||
});
|
||||
|
||||
for await (const chunk of stream) {
|
||||
process.stdout.write(chunk.message.content);
|
||||
}
|
||||
}
|
||||
|
||||
await streamChat();
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
function sortingAlgorithm(x: number[]): number[] {
|
||||
for (let i = 0; i < x.length; i++) {
|
||||
for (let j = 0; j < x.length - 1; j++) {
|
||||
if (x[j] > x[j + 1]) {
|
||||
[x[j], x[j + 1]] = [x[j + 1], x[j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
5
bun.lock
5
bun.lock
|
|
@ -4,6 +4,7 @@
|
|||
"": {
|
||||
"dependencies": {
|
||||
"chalk": "^5.5.0",
|
||||
"ollama": "^0.5.17",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.2.1",
|
||||
|
|
@ -15,6 +16,10 @@
|
|||
|
||||
"chalk": ["chalk@5.5.0", "", {}, "sha512-1tm8DTaJhPBG3bIkVeZt1iZM9GfSX2lzOeDVZH9R9ffRHpmHvxZ/QhgQH/aDTkswQVt+YHdXAdS/In/30OjCbg=="],
|
||||
|
||||
"ollama": ["ollama@0.5.17", "", { "dependencies": { "whatwg-fetch": "^3.6.20" } }, "sha512-q5LmPtk6GLFouS+3aURIVl+qcAOPC4+Msmx7uBb3pd+fxI55WnGjmLZ0yijI/CYy79x0QPGx3BwC3u5zv9fBvQ=="],
|
||||
|
||||
"undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="],
|
||||
|
||||
"whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
import { readdir, stat } from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { exec } from 'child_process';
|
||||
|
||||
const videoExtensions = ['mp4', 'avi', 'mov', 'mkv', 'flv', 'wmv', 'mpeg', 'mpg'];
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const files = await readdir('.');
|
||||
for (const file of files) {
|
||||
const stats = await stat(file);
|
||||
if (!stats.isFile()) continue;
|
||||
|
||||
const ext = path.extname(file).slice(1).toLowerCase();
|
||||
if (videoExtensions.includes(ext) && !file.startsWith('HEVC_')) {
|
||||
const newFileName = 'HEVC_' + file;
|
||||
const command = `ffmpeg -i "${file}" -c:v hevc_nvenc -preset slow -crf 23 -c:a aac "${newFileName}"`;
|
||||
|
||||
exec(command, (err) => {
|
||||
if (err) console.error(`Conversion failed for ${file}: ${err}`);
|
||||
else console.log(`Converted ${file} → ${newFileName}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error processing files:', err);
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import { exec } from 'child_process';
|
||||
import { readdir, stat } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const currentDir = './'; // Текущая директория
|
||||
|
||||
function isVideoFile(filePath: string): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
stat(filePath, (err, stats) => {
|
||||
if (err) {
|
||||
console.error(`Ошибка при получении информации о файле ${filePath}:`, err);
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
const ext = path.extname(filePath).toLowerCase();
|
||||
const isVideo = ['.mp4', '.mov', '.avi', '.mkv'].includes(ext);
|
||||
resolve(isVideo && stats.size > 0); // Убеждаемся, что файл не пустой
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function compressVideoWithFFmpeg(filePath: string): void {
|
||||
const outputFilePath = `HEVC_${path.basename(filePath)}`;
|
||||
exec(`ffmpeg -i ${filePath} -c:v hevc_nvenc ${outputFilePath}`, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error('Ошибка при сжатии видео:', error);
|
||||
return;
|
||||
}
|
||||
if (stderr) {
|
||||
console.error('FFmpeg ошибка:', stderr);
|
||||
return;
|
||||
}
|
||||
console.log(`Сжата файл: ${filePath} в ${outputFilePath}`);
|
||||
});
|
||||
}
|
||||
|
||||
function walkThroughDirectory(dir: string): void {
|
||||
readdir(dir, { withFileTypes: true }, (err, files) => {
|
||||
if (err) {
|
||||
console.error('Ошибка при чтении директории:', err);
|
||||
return;
|
||||
}
|
||||
files.forEach((file) => {
|
||||
const fullPath = path.join(dir, file.name);
|
||||
if (file.isDirectory()) {
|
||||
walkThroughDirectory(fullPath); // Рекурсивно обходим поддиректории
|
||||
} else {
|
||||
isVideoFile(fullPath).then((isVideo) => {
|
||||
if (isVideo) {
|
||||
compressVideoWithFFmpeg(fullPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
walkThroughDirectory(currentDir);
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import {spawn} from 'child_process';
|
||||
import {readFileSync} from 'node:fs';
|
||||
|
||||
export function runInBackground(command: string, args?: string[]) {
|
||||
const proc = spawn(command, args ?? [], {detached: true, stdio: 'ignore'});
|
||||
proc.unref();
|
||||
return proc.pid;
|
||||
}
|
||||
|
||||
export const getStdin = () => readFileSync(0, 'utf8');
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
"@types/node": "^24.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^5.5.0"
|
||||
"chalk": "^5.5.0",
|
||||
"ollama": "^0.5.17"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue