let handler = async (m, { conn, text }) => { conn.hartatahta = conn.hartatahta ? conn.hartatahta : {} if (m.chat in conn.hartatahta) throw 'Masih ada yang sedang membuat\nTeks Harta Tahta\ndi chat ini... tunggu sampai selesai' else conn.hartatahta[m.chat] = true m.reply('_Sedang membuat..._\n*Mohon tunggu sekitar 1 menit*') try { let img = await ht(text ? text : ':v') conn.sendFile(m.chat, img, 'Harta Tahta.png', '*© Nurutomo*\nMade with FFmpeg', m) } finally { delete conn.hartatahta[m.chat] } } handler.help = ['tahta <teks>'] handler.tags = ['nulis'] handler.command = /^((harta)?tahta)$/i handler.limit = true export default handler import { spawn } from 'child_process' import { readdirSync, readFileSync, unlinkSync } from 'fs' import { join } from 'path' let __dirname = global.__dirname(import.meta.url) let src = join(__dirname, '../src/') let tmp = join(__dirname, '../tmp/') let _font = join(src, 'font') let aesthetic = join(src, 'Aesthetic') function ht(text = '') { return new Promise((resolve, reject) => { let img = join(aesthetic, pickRandom(readdirSync(aesthetic))) let font = join(_font, 'Roboto-Black.ttf') let w = 1024 let h = w let s = w + 'x' + h let xF = `(${noise('X', 2, w, 1)}+${noise('Y', 1, h, 1)})/2+128` let yF = `((${pickRandom(['', '-'])}${45 * w / 2048}*${pickRandom(['sin', 'cos'])}(X/${w}*4*PI))+${noise('X', 5, w, 0.8)}+${noise('Y', 2, h, 1)})/1.7+128` let fsize = 320 / 2048 * w let lh = 1.5 let format = '' let layers = [ `[v:0]scale=${s}${format}[im]`, textArgs('HARTA', 'black', 'white', fsize, font, '(w-text_w)/2', `(h-text_h)/2-(text_h*${lh})`, w, h) + format + '[top]', textArgs('TAHTA', 'black', 'white', fsize, font, '(w-text_w)/2', `(h-text_h)/2`, w, h) + format + '[mid]', textArgs(text, 'black', 'white', fsize, font, '(w-text_w)/2', `(h-text_h)/2+(text_h*${lh})`, w, h) + format + '[bot]', '[top][mid]blend=all_mode=addition[con]', '[con][bot]blend=all_mode=addition[txt]', `nullsrc=s=${s},geq='r=${xF}:g=${xF}:b=${xF}'[dx]`, `nullsrc=s=${s},geq='r=${yF}:g=${yF}:b=${yF}'[dy]`, '[txt][dx][dy]displace[wa]', '[im][wa]blend=all_mode=multiply:all_opacity=1' ] let o = 1 * new Date + '_harta_tahta.png' o = join(tmp, o) let args = [ '-y', '-i', img, '-filter_complex', layers.join(';'), '-frames:v', '1', o ] spawn('ffmpeg', args) .on('error', reject) .on('close', () => { try { resolve(readFileSync(o)) unlinkSync(o) } catch (e) { reject(e) } }) //.stderr.on('data', a => console.log(a+'')) }) } function noise(_var, depth = 4, s = 1024, freq) { let forms = [] for (let i = 0; i < depth; i++) forms.push( formula( _var, freq * rand(40, 80) * (s / 2048) / s * ((i + 1) / 5), rand(-Math.PI, Math.PI), (i + 1) / depth * 8, 0 ) ) return forms.join('+') } function formula(_var, freq, offset, amp, add) { return `(${add.toFixed(3)}+${amp.toFixed(4)}*sin(${offset.toFixed(6)}+2*PI*${_var}*${freq.toFixed(6)}))` } function textArgs(text, background, color, size, fontfile, x = '200', y = '200', w = 1024, h = 1024) { return `color=${background}:s=${w}x${h},drawtext=text='${text.replace(/[\\]/g, '\\$&')}':fontfile='${fontfile.replace(/[\\]/g, '\\$&')}':x=${x}:y=${y}:fontsize=${size}:fontcolor=${color}` } function pickRandom(list) { return list[Math.floor(Math.random() * list.length)] } function rand(min, max, q = 0.001) { return Math.floor((Math.random() * (max - min)) / q) * q }