Git Product home page Git Product logo

mediaforge's Introduction

MediaForge

MediaForge Discord uptime

Total Lines wakatime stars built with immense swag

ko-fi

A Discord bot for editing and creating videos, images, GIFs, and more!

general technical info about the bot

  • inspired by esmBot
  • uses discord.py 2
  • uses libvips for captioning
  • uses FFmpeg for media processing

self-host with docker

to install

All you need to install yourself is Docker Desktop

as of writing, a working docker copy of MediaForge takes up ~3.46GB. if this is a concern and you are using some of the apt libraries MediaForge does, see to self-host natively

once that's installed, run these commands in your terminal of choice.

docker build -t melodyflorum/mediaforge https://github.com/reticivis-net/mediaforge.git
docker run -it --cap-add SYS_NICE --shm-size 8G --name mediaforge melodyflorum/mediaforge

on linux, you may need to run docker with sudo

replace 8G with how much free RAM your system has that you would like to give MediaForge (in gigabytes). At least 1G is suggested. Making this too small can make commands fail due to not enough space, as the /dev/shm in-memory filesystem is, by default, MediaForge's sole temporary directory. Override the override_temp_dir option in config.py if you can't allocate enough memory.

if the installation succeeded, you should be prompted with some options. you'll need to select "Edit Config". this will open a text editor within your terminal. the 2 required config settings to change for proper functionality are the discord and tenor tokens. be sure not to add or remove quotes. press CTRL+S to save and CTRL+X to exit.

if you don't want to use the built-in text editor, you can get the example config from GitHub, hold down CTRL+K to clear the file and then use CTRL+V to paste in your config.

to run

run in your favorite terminal:

docker start -ia mediaforge

by default, MediaForge will await user input for 10 seconds before attempting to run the bot automatically.

to stop

killing the terminal window/CTRL+C won't kill the bot, because docker runs in the background.

to kill the bot, run

docker stop mediaforge

to limit resource consumption

since docker is very containerized, you can easily limit the amount of resources it's allowed to consume.

the main command to do this is docker update, though most of these arguments can be passed verbatim to docker run during setup.

the most useful options are --memory and --cpus.

for example, this is (as of writing) what the official MediaForge bot uses:

docker update --memory 9000M --memory-swap -1 --cpus "3.9" mediaforge
  • --memory 9000M: this limits it to 9gb (9000mb) of physical memory
  • --memory-swap -1: this allows it to use as much swap memory as it wants (swap memory is temporarily storing memory on disk)
  • --cpus "3.9": the host server has 4 cores, so this allows it to use "3.9"/4 (97.5%) of the PC's CPU time.

Automode

this is designed to work with hosting providers where terminal control is not possible. There are 3 arguments to this mode that can be set as docker build arguments or environment variables . AUTOMODE: set to "ON" to enable automode AUTOUPDATE: set to "ON" to update code and packages every run CONFIG: base64 encoded version of your config file.

to encode base 64

on linux:
  • base64 config.py prints the output to terminal
  • base64 config.py > config.txt writes the output to config.txt
with python:
import base64

with open("config.py", "rb") as f:
    out = base64.b64encode(f.read())
print(out)  # write to terminal
# write to file
with open("config.txt", "wb+") as f:
    f.write(out)

to self-host natively

MediaForge is a complex application and manually installing all dependencies is a headache. for almost all use cases, the docker distribution is much better.

summary

ensure your OS is one of the supported OSes, then install the python libraries and the non-python libraries, set up the config, and run

supported OSes

built and tested on windows 10/11 and debian 10/buster (inside docker). these 2 OSes (and their successors) will continue to be officially supported.

will probably work on macos and other linux/unix distros if the below libraries are available but theyre untested and unsupported. just replace apt-get with your system's preferred package manager (brew for macos)

on Windows, color emojis won't work. no idea why, just is a windows pango bug.

python libraries

  • This project uses poetry, run poetry install to install the required dependencies.
    • install poetry with pip install poetry
    • part of pyvips is built from source on installation.
      • on Windows this will require the MSVC compiler, which is an optional component of Visual Studio
      • on Linux this will require gcc, installable by sudo apt-get install gcc

non-python libraries

the bot uses many external CLI programs for media processing.

  • FFmpeg - not included but easily installable on windows and linux
    • If installing on linux, ensure that ffmpeg version >= 5
  • libvips - installable on linux with sudo apt-get install libvips-dev . windows instructions here
  • ImageMagick - not included but downloadable here
  • TTS
    • on linux, this uses mimic. a pre-compiled binary is included.
      • the male and female voices are downloaded from mimic's repo on bot start if they are not detected. if you want to re-download for some reason, delete the 2 files ending in .flitefox in tts/
    • on windows, powershell is used to access Windows's native TTS . Both are included in modern versions of Windows, but ensure powershell is in the system path.
    • the "retro" voice uses sam-cli. it is included, but it requires node.js to be installed and added to the system path - pretty sure both the windows & linux installers add it to path on installation but cant hurt to check

config

  • create a copy of config.example.py and name it config.py.
  • insert/change the appropriate config settings such as your discord api token. be sure not to add or remove quotes.
  • the 2 required config settings to change for proper functionality are the discord and tenor tokens.

python

  • developed and tested on python 3.11. use that or a later compatible version

to run

  • once you've set up all of the libraries, just run the program with poetry run python src/main.py ( or poetry run python3.11 src/main.py or whatever your python is named). make sure it can read and write to the directory it lives in and also access/execute all the aforementioned libraries
    • if poetry isn't installing on the right python version, run <yourpython> -m pip instead of pip and <yourpython> -m poetry instead of poetry
  • terminate the bot by running the shutdown command, this will probably close better than a termination

legal stuff

terms of service

privacy policy

mediaforge's People

Contributors

reticivis-net avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mediaforge's Issues

$addaudio Stream map '0:v' matches no streams.

DATETIME:2021-04-06 13:58:52.097055
COMMAND:$addaudio
TRACEBACK:
improcessing.CMDError: ffmpeg version 4.3.1-0york0~18.04 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
  configuration: --prefix=/usr --extra-version='0york0~18.04' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libzimg --enable-pocketsphinx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, mp3, from 'temp/BZZkDdRu.mp3':
  Metadata:
    major_brand     : dash
    minor_version   : 0
    compatible_brands: iso6mp41
    artist          : MediaForge
    encoder         : Lavf58.45.100
  Duration: 00:03:55.15, start: 0.025057, bitrate: 128 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc58.91
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'temp/IfbZwzUT.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
  Duration: 00:00:08.54, start: 0.000000, bitrate: 821 kb/s
    Stream #1:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x592, 680 kb/s, 60 fps, 60 tbr, 15360 tbn, 120 tbc (default)
    Metadata:
      handler_name    : Vireo Eyes v2.6.2
    Stream #1:1(und): Audio: mp3 (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 127 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Stream map '0:v' matches no streams.
To ignore this, add a trailing '?' to the map.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 546, in addaudio
    await improcess(ctx, improcessing.addaudio, [["IMAGE", "GIF", "VIDEO", "AUDIO"], ["AUDIO"]])
  File "main.py", line 320, in improcess
    raise e
  File "main.py", line 302, in improcess
    result = await func(filesforcommand, *args)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 667, in addaudio
    await run_command("ffmpeg", "-i", media, "-i", audio, "-filter_complex",
  File "/home/hex/Desktop/captionbot/improcessing.py", line 134, in run_command
    raise CMDError(f"Command {args} failed.") from CMDError(stderr.decode().strip())
improcessing.CMDError: Command ('ffmpeg', '-i', 'temp/BZZkDdRu.mp3', '-i', 'temp/IfbZwzUT.mp4', '-filter_complex', '[0:a][1:a]amix=inputs=2:dropout_transition=100000:duration=longest[a];[a]volume=2[a]', '-map', '0:v', '-map', '[a]', '-c:a', 'aac', 'temp/RptHFkWq.mp3') failed.

To ignore this, add a trailing '?' to the map.

thats probably the fix lol

video captioning can vary in size with a single size input

ValueError: invalid literal for int() with base 10: '';

DATETIME:2021-03-31 20:33:39.181706
COMMAND:$freezemotivateaudio HOLY SHOOT!|shostakovich copyed mom three!!!!
TRACEBACK:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 525, in freezemotivateaudio
    await improcess(ctx, improcessing.freezemotivate, [["VIDEO", "GIF"], ["AUDIO"]], *caption)
  File "main.py", line 320, in improcess
    raise e
  File "main.py", line 302, in improcess
    result = await func(filesforcommand, *args)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 790, in freezemotivate
    framecount = int(framecount)
ValueError: invalid literal for int() with base 10: ''

image

the bot replied to the same message 3 fucking times

$videodl reports IndexError: list index out of range when no video within size constraint is found

DATETIME:2021-04-08 18:11:14.279025
COMMAND:$ytdl https://www.youtube.com/watch?v=6XPP7vgkfog
TRACEBACK:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 857, in videodl
    r = await improcessing.run_in_exec(ytdownload, url, form)
  File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 345, in <lambda>
    return loop.run_in_executor(None, lambda: func(*args, **kwargs))
  File "main.py", line 84, in ytdownload
    filename = glob.glob(name + ".*")[0]
IndexError: list index out of range

a try block is needed to properly catch and label this bug for the user.

No imgur gif support

So i was trying to turn a gif into mp4 but instead gave me this error

DATETIME:2022-02-01 10:42:49.475421
COMMAND:$tomp4
TRACEBACK:
Traceback (most recent call last):
File "/home/hex/.cache/pypoetry/virtualenvs/mediaforge-4kydknjC-py3.8/lib/python3.8/site-packages/nextcord/ext/commands/core.py", line 168, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 1505, in tovideo
await improcess(ctx, improcessing.giftomp4, [["GIF"]])
File "main.py", line 453, in improcess
urls = await imagesearch(ctx, len(allowedtypes))
File "main.py", line 305, in imagesearch
hm = await handlemessagesave(m)
File "main.py", line 258, in handlemessagesave
tenor = await fetch(
File "/home/hex/Desktop/captionbot/improcessing.py", line 1432, in fetch
response.raise_for_status()
File "/home/hex/.cache/pypoetry/virtualenvs/mediaforge-4kydknjC-py3.8/lib/python3.8/site-packages/aiohttp/client_reqrep.py", line 1004, in raise_for_status
raise ClientResponseError(
aiohttp.client_exceptions.ClientResponseError: 400, message='Bad Request', url=URL('https://api.tenor.com/v1/gifs?ids=https://imgur.com/OPLGlyW&key=ECYW4F9SR5I6')

Add $uncaption command.

A command I often used to use on esmBot (before I switched to mediaforge) was &uncaption (Recropping the image, gif, etc.). I would love if you could make it work on both $caption and $esmcaption (I personally don't like the default font on $caption).

Also, unrelevant question: I see that there's feature requests both in Issues and Discussions. Where do you prefer people to post feature requests?

$flanger

https://ffmpeg.org/ffmpeg-filters.html#flanger

Apply a flanging effect to the audio.

The filter accepts the following options:

delay
Set base delay in milliseconds. Range from 0 to 30. Default value is 0.

depth
Set added sweep delay in milliseconds. Range from 0 to 10. Default value is 2.

regen
Set percentage regeneration (delayed signal feedback). Range from -95 to 95. Default value is 0.

width
Set percentage of delayed signal mixed with original. Range from 0 to 100. Default value is 71.

speed
Set sweeps per second (Hz). Range from 0.1 to 10. Default value is 0.5.

shape
Set swept wave shape, can be triangular or sinusoidal. Default value is sinusoidal.

phase
Set swept wave percentage-shift for multi channel. Range from 0 to 100. Default value is 25.

interp
Set delay-line interpolation, linear or quadratic. Default is linear.

lol

ok ima use my alt bye

custom emojis don't work

Describe the bug
discord custom emojis are displayed in all caption/creation commands as their internal string (e.g. <a:working:803801825605320754>)

Expected behavior
they display properly as inline images

Screenshots
image

$addaudio doesn't work

It always has worked before, it started not working yesterday.
This is the copy paste of the error message:

IndexError: Command raised an exception: IndexError: list index out of range

DATETIME:2021-09-27 21:43:06.621508
COMMAND:$addaudio
TRACEBACK:
Traceback (most recent call last):
File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/nextcord/ext/commands/core.py", line 168, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 758, in addaudio
await improcess(ctx, improcessing.addaudio, [["IMAGE", "GIF", "VIDEO", "AUDIO"], ["AUDIO"]])
File "main.py", line 428, in improcess
if await improcessing.is_apng(file):
File "/home/hex/Desktop/captionbot/improcessing.py", line 157, in is_apng
return data["streams"][0]["codec_name"] == "apng"
IndexError: list index out of range

Help, I got banned?

Hi, I got banned from this bot on discord because I tried using a big caption multiple times. I’m really confused and could you please help me with this? My discord username is Remainings#2000.

Output file #0 does not contain any stream when using $trim 0

$trim 0 shouldnt be allowed, this needs to be properly handled.

DATETIME:2021-04-09 10:08:09.227693
COMMAND:$trim 0 4
TRACEBACK:
improcessing.CMDError: Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'temp/uRGmjBtV.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.45.100
  Duration: 00:00:00.00, bitrate: N/A
Output #0, mp4, to 'temp/dmfeZige.mp4':
Output file #0 does not contain any stream

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 863, in trim
    await improcess(ctx, improcessing.trim, [["VIDEO", "GIF", "AUDIO"]], length, start)
  File "main.py", line 332, in improcess
    raise e
  File "main.py", line 320, in improcess
    result = await improcessing.assurefilesize(result, ctx)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 273, in assurefilesize
    media = await reencode(media)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 485, in reencode
    await run_command("ffmpeg", "-hide_banner", "-i", mp4, "-c:v", "libx264", "-c:a", "copy", "-pix_fmt", "yuv420p",
  File "/home/hex/Desktop/captionbot/improcessing.py", line 135, in run_command
    raise CMDError(f"Command {args} failed.") from CMDError(stderr.decode().strip())
improcessing.CMDError: Command ('ffmpeg', '-hide_banner', '-i', 'temp/uRGmjBtV.mp4', '-c:v', 'libx264', '-c:a', 'copy', '-pix_fmt', 'yuv420p', '-max_muxing_queue_size', '9999', '-vf', 'scale=trunc(iw/2)*2:trunc(ih/2)*2', 'temp/dmfeZige.mp4') failed.

Multilingual support

This is a very ambitious idea that would require several different huge changes.

  • Refactor basically the entire codebase to get basically every single string from a function (so it can return whatever language was selected)
  • redo the help text for basically every command. I planned to do this to make the help commands proper PEP docstring format but now I'll have to offload the help text to either some king of Lang file or just dynamically replace the docstring for non English languages
  • find some way to dynamically inject aliases into commands
  • learn how to do proper language file support or whatever
  • Actually get people to translate all of the strings (currently there's one person offering to do Arabic which is why I made this issue)

It's doable certainly but not easy.

Command ('ffmpeg', '-i', 'temp/gYtSDnFo.mp4', '-ar', '48000', '-af', 'asetrate=r=15481909,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,aresample=48000', '-strict', '-1', '-c:a', 'aac', 'temp/NAKhNltx.mp4') failed.

DATETIME:2021-11-14 15:11:30.485844
COMMAND:$pitch 100
TRACEBACK:
improcessing.CMDError: ffmpeg version 4.3.2-0york018.04 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 7 (Ubuntu 7.5.0-3ubuntu1
18.04)
configuration: --prefix=/usr --extra-version='0york0~18.04' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libzimg --enable-pocketsphinx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'temp/gYtSDnFo.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
Duration: 00:00:18.95, start: 0.000000, bitrate: 3321 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1920x1080 [SAR 1:1 DAR 16:9], 3193 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
[Parsed_atempo_1 @ 0x562c5b4bd580] Failed to configure input pad on Parsed_atempo_1
Error reinitializing filters!
Failed to inject frame into filter network: Cannot allocate memory
Error while processing the decoded data for stream #0:1
Conversion failed!

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/nextcord/ext/commands/core.py", line 168, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 1073, in pitch
await improcess(ctx, improcessing.pitch, [["VIDEO", "AUDIO"]], numofhalfsteps)
File "main.py", line 481, in improcess
raise e
File "main.py", line 460, in improcess
result = await func(filesforcommand, *args)
File "/home/hex/Desktop/captionbot/improcessing.py", line 1185, in pitch
await run_command("ffmpeg", "-i", file, "-ar", "48000", "-af", af, "-strict", "-1", "-c:a",
File "/home/hex/Desktop/captionbot/improcessing.py", line 149, in run_command
raise CMDError(f"Command {args} failed.") from CMDError(stdout.decode().strip() + stderr.decode().strip())
improcessing.CMDError: Command ('ffmpeg', '-i', 'temp/gYtSDnFo.mp4', '-ar', '48000', '-af', 'asetrate=r=15481909,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,atempo=0.5263426013194779,aresample=48000', '-strict', '-1', '-c:a', 'aac', 'temp/NAKhNltx.mp4') failed.

IndexError: list index out of range using $speed on audio

DATETIME:2021-04-01 18:02:42.261900
COMMAND:$speed 2
TRACEBACK:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 785, in spcommand
    await improcess(ctx, improcessing.speed, [["VIDEO", "GIF"]], speed)
  File "main.py", line 320, in improcess
    raise e
  File "main.py", line 302, in improcess
    result = await func(filesforcommand, *args)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 543, in speed
    fps = await get_frame_rate(file)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 152, in get_frame_rate
    rate = out.split('=')[1].strip()[1:-1].split('/')
IndexError: list index out of range```

$deshake

https://ffmpeg.org/ffmpeg-filters.html#toc-deshake)

your idea is make this command from mediaforge

Attempt to fix small changes in horizontal and/or vertical shift. This filter helps remove camera shake from hand-holding a camera, bumping a tripod, moving on a vehicle, etc.

The filter accepts the following options:

x
y
w
h
Specify a rectangular area where to limit the search for motion vectors. If desired the search for motion vectors can be limited to a rectangular area of the frame defined by its top left corner, width and height. These parameters have the same meaning as the drawbox filter which can be used to visualise the position of the bounding box.

This is useful when simultaneous movement of subjects within the frame might be confused for camera motion by the motion vector search.

If any or all of x, y, w and h are set to -1 then the full frame is used. This allows later options to be set without specifying the bounding box for the motion vector search.

Default - search the whole frame.

rx
ry
Specify the maximum extent of movement in x and y directions in the range 0-64 pixels. Default 16.

edge
Specify how to generate pixels to fill blanks at the edge of the frame. Available values are:

‘blank, 0’
Fill zeroes at blank locations

‘original, 1’
Original image at blank locations

‘clamp, 2’
Extruded edge value at blank locations

‘mirror, 3’
Mirrored edge at blank locations

Default value is ‘mirror’.

blocksize
Specify the blocksize to use for motion search. Range 4-128 pixels, default 8.

contrast
Specify the contrast threshold for blocks. Only blocks with more than the specified contrast (difference between darkest and lightest pixels) will be considered. Range 1-255, default 125.

search
Specify the search strategy. Available values are:

‘exhaustive, 0’
Set exhaustive search

‘less, 1’
Set less exhaustive search.

Default value is ‘exhaustive’.

filename
If set then a detailed log of the motion search is written to the specified file.

idk what this is, but this happened when i pinged the bot for help

DATETIME:2022-02-04 20:23:06.523526
COMMAND:<@!780570413767983122> help
TRACEBACK:
Traceback (most recent call last):
File "/home/hex/.cache/pypoetry/virtualenvs/mediaforge-4kydknjC-py3.8/lib/python3.8/site-packages/nextcord/ext/commands/core.py", line 168, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 1992, in help
await ctx.reply(embed=embed)
File "/home/hex/.cache/pypoetry/virtualenvs/mediaforge-4kydknjC-py3.8/lib/python3.8/site-packages/nextcord/ext/commands/context.py", line 400, in reply
return await self.message.reply(content, **kwargs)
File "main.py", line 68, in safe_reply
await self.channel.fetch_message(self.id)
File "/home/hex/.cache/pypoetry/virtualenvs/mediaforge-4kydknjC-py3.8/lib/python3.8/site-packages/nextcord/abc.py", line 1497, in fetch_message
data = await self._state.http.get_message(channel.id, id)
File "/home/hex/.cache/pypoetry/virtualenvs/mediaforge-4kydknjC-py3.8/lib/python3.8/site-packages/nextcord/http.py", line 275, in request
async with self.__session.request(method, url, **kwargs) as response:
File "/home/hex/.cache/pypoetry/virtualenvs/mediaforge-4kydknjC-py3.8/lib/python3.8/site-packages/aiohttp/client.py", line 1138, in aenter
self._resp = await self._coro
File "/home/hex/.cache/pypoetry/virtualenvs/mediaforge-4kydknjC-py3.8/lib/python3.8/site-packages/aiohttp/client.py", line 634, in _request
break
File "/home/hex/.cache/pypoetry/virtualenvs/mediaforge-4kydknjC-py3.8/lib/python3.8/site-packages/aiohttp/helpers.py", line 721, in exit
raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError

$help | [Errno 32] Broken pipe

Happened when using $help

DATETIME:2021-12-30 15:32:13.215997
COMMAND:$help
TRACEBACK:
Traceback (most recent call last):
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/nextcord/ext/commands/core.py", line 168, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 1979, in help
    await ctx.reply(embed=embed)
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/nextcord/ext/commands/context.py", line 400, in reply
    return await self.message.reply(content, **kwargs)
  File "main.py", line 70, in safe_reply
    return await self.orig_reply(*args, **kwargs)
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/nextcord/message.py", line 1564, in reply
    return await self.channel.send(content, reference=self, **kwargs)
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/nextcord/abc.py", line 1422, in send
    data = await state.http.send_message(
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/nextcord/http.py", line 273, in request
    async with self.__session.request(method, url, **kwargs) as response:
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/aiohttp/client.py", line 1012, in __aenter__
    self._resp = await self._coro
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/aiohttp/client.py", line 504, in _request
    await resp.start(conn)
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/aiohttp/client_reqrep.py", line 847, in start
    message, payload = await self._protocol.read()  # type: ignore  # noqa
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/aiohttp/streams.py", line 591, in read
    await self._waiter
aiohttp.client_exceptions.ClientOSError: [Errno 32] Broken pipe

image

Message: invalid session id

Describe the bug
Error message when using $freezemotivate on this gif:
https://tenor.com/view/nekohime-anime-drink-hot-drink-gif-14698957

Screenshots
image

Traceback
DATETIME:2021-04-28 18:12:11.238543
COMMAND:$freezemotivate why is she drinking|piss
TRACEBACK:
concurrent.futures.process._RemoteTraceback:
"""
Traceback (most recent call last):
File "/usr/lib/python3.8/concurrent/futures/process.py", line 239, in _process_worker
r = call_item.fn(*call_item.args, **call_item.kwargs)
File "/home/hex/Desktop/captionbot/improcessing.py", line 52, in pass_temp_session
result = fn(*args, **kwargs)
File "/home/hex/Desktop/captionbot/captionfunctions.py", line 90, in motivate
return htmlcap("captionhtml/motivate.html", image, caption, tosavename)
File "/home/hex/Desktop/captionbot/captionfunctions.py", line 63, in htmlcap
chromiumrender.html2png(torender, tosavename)
File "/home/hex/Desktop/captionbot/chromiumrender.py", line 98, in html2png
driver.set_window_size(1, 1)
File "/usr/local/lib/python3.8/dist-packages/selenium/webdriver/remote/webdriver.py", line 1090, in set_window_size
self.set_window_rect(width=int(width), height=int(height))
File "/usr/local/lib/python3.8/dist-packages/selenium/webdriver/remote/webdriver.py", line 1180, in set_window_rect
return self.execute(Command.SET_WINDOW_RECT, {"x": x, "y": y,
File "/usr/local/lib/python3.8/dist-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/usr/local/lib/python3.8/dist-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidSessionIdException: Message: invalid session id

"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 521, in freezemotivate
await improcess(ctx, improcessing.freezemotivate, [["VIDEO", "GIF"]], *caption)
File "main.py", line 332, in improcess
raise e
File "main.py", line 314, in improcess
result = await func(filesforcommand, *args)
File "/home/hex/Desktop/captionbot/improcessing.py", line 795, in freezemotivate
clastframe = await handleanimated(lastframe, captionfunctions.motivate, None, *caption)
File "/home/hex/Desktop/captionbot/improcessing.py", line 401, in handleanimated
result = await renderpool.submit(capfunction, media, caption)
File "/home/hex/Desktop/captionbot/improcessing.py", line 71, in submit
return await fut
selenium.common.exceptions.InvalidSessionIdException: Message: invalid session id

[Errno 2] No such file or directory: 'ffprobe'

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Traceback
If the bot uploaded a txt file with the error, please upload it here.

Additional context
Add any other context about the problem here.

$volume 0 ValueError: math domain error

DATETIME:2021-04-06 13:58:04.808059
COMMAND:$volume 0
TRACEBACK:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 709, in volume
    await improcess(ctx, improcessing.volume, [["VIDEO", "AUDIO"]], volume)
  File "main.py", line 320, in improcess
    raise e
  File "main.py", line 302, in improcess
    result = await func(filesforcommand, *args)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 898, in volume
    vol = 10 * math.log(vol, 2)
ValueError: math domain error

Unable to run `main.py`

Describe the bug
The bug takes place when I attempt to start the bot.

To Reproduce
Steps to reproduce the behavior:

  1. Run the command python main.py
  2. See error

Expected behavior
This is supposed to import the libraries and start the bot, but instead gives me this error.

Screenshots
image

Traceback
None.

Additional context
None.

Bot thinks non-file video embeds, such as youtube, are downloadable video files

image

DATETIME:2021-04-06 13:52:20.268364
COMMAND:$addaudio
TRACEBACK:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 546, in addaudio
    await improcess(ctx, improcessing.addaudio, [["IMAGE", "GIF", "VIDEO", "AUDIO"], ["AUDIO"]])
  File "main.py", line 274, in improcess
    files = await saveurls(urls)
  File "main.py", line 204, in saveurls
    files.append(await saveurl(url))
  File "main.py", line 83, in saveurl
    raise Exception("Cannot determine filesize!")
Exception: Cannot determine filesize!

add audio pitch wobbler

this would compliment $magik very well, though i'm not sure if it's an effect easily possible with FFmpeg... anyone know an easy CLI/python way to do this?

invalid literal for int() with base 10: ''

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Traceback
If the bot uploaded a txt file with the error, please upload it here.

Additional context
Add any other context about the problem here.

$datamosh

so if you are intrested of glitches, why dont you make the command $datamosh pls?

n

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Traceback
If the bot uploaded a txt file with the error, please upload it here.

Additional context
Add any other context about the problem here.

400, message='Bad Request', url=URL('https://api.tenor.com/v1/gifs?ids=https://gfycat.com/requiredclearcuscus&key=ECYW4F9SR5I6')

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Traceback
If the bot uploaded a txt file with the error, please upload it here.

Additional context
Add any other context about the problem here.

OSError: image file is truncated (11 bytes not processed); bug in $sus

COMMAND:$sus when the impooooooooooooooooster is sus!😳
TRACEBACK:
concurrent.futures.process._RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/usr/lib/python3.8/concurrent/futures/process.py", line 239, in _process_worker
    r = call_item.fn(*call_item.args, **call_item.kwargs)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 51, in pass_temp_session
    result = fn(*args, **kwargs)
  File "/home/hex/Desktop/captionbot/sus.py", line 91, in sus
    letter = master_im.crop((x_coords[0], 0, x_coords[1], y_coord_split))
  File "/usr/local/lib/python3.8/dist-packages/PIL/Image.py", line 1127, in crop
    self.load()
  File "/usr/local/lib/python3.8/dist-packages/PIL/ImageFile.py", line 259, in load
    raise OSError(
OSError: image file is truncated (11 bytes not processed)
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 1000, in jermatext
    await improcess(ctx, sus.sus, [], text)
  File "main.py", line 320, in improcess
    raise e
  File "main.py", line 304, in improcess
    result = await renderpool.submit(func, *args)
  File "/home/hex/Desktop/captionbot/improcessing.py", line 70, in submit
    return await fut
OSError: image file is truncated (11 bytes not processed)

image file is truncated (11 bytes not processed)

OSError: image file is truncated (11 bytes not processed)

!sus is broken

image

Error log:
DATETIME:2021-04-05 11:23:37.401185
COMMAND:$sus when the adventure is bizzare!
TRACEBACK:
concurrent.futures.process._RemoteTraceback:
"""
Traceback (most recent call last):
File "/usr/lib/python3.8/concurrent/futures/process.py", line 239, in _process_worker
r = call_item.fn(*call_item.args, **call_item.kwargs)
File "/home/hex/Desktop/captionbot/improcessing.py", line 51, in pass_temp_session
result = fn(*args, **kwargs)
File "/home/hex/Desktop/captionbot/sus.py", line 91, in sus
letter = master_im.crop((x_coords[0], 0, x_coords[1], y_coord_split))
File "/usr/local/lib/python3.8/dist-packages/PIL/Image.py", line 1127, in crop
self.load()
File "/usr/local/lib/python3.8/dist-packages/PIL/ImageFile.py", line 259, in load
raise OSError(
OSError: image file is truncated (11 bytes not processed)
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/usr/local/lib/python3.8/dist-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 1000, in jermatext
await improcess(ctx, sus.sus, [], text)
File "main.py", line 320, in improcess
raise e
File "main.py", line 304, in improcess
result = await renderpool.submit(func, *args)
File "/home/hex/Desktop/captionbot/improcessing.py", line 70, in submit
return await fut
OSError: image file is truncated (11 bytes not processed)

General purpose command like $eminem/$stuff for any image

There's 3 commands now that use the same underlying code but different images, there should be a general purpose command for captioning anything with any image and text.

Not the easiest thing because currently I can only pass one image to the html renderer but that isn't a hard fix :)

Inspired by #34

$chromashift

why dont you make this https://ffmpeg.org/ffmpeg-filters.html#toc-chromashift

Shift chroma pixels horizontally and/or vertically.

The filter accepts the following options:

cbh
Set amount to shift chroma-blue horizontally.

cbv
Set amount to shift chroma-blue vertically.

crh
Set amount to shift chroma-red horizontally.

crv
Set amount to shift chroma-red vertically.

edge
Set edge mode, can be smear, default, or warp.

aiohttp.client_exceptions.ClientOSError: Command raised an exception: ClientOSError: [Errno 32] Broken pipe

Happened while trying to vertically stack a gif and a static image

COMMAND:$vstack
TRACEBACK:
Traceback (most recent call last):
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/nextcord/ext/commands/core.py", line 168, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 1130, in vstack
    await improcess(ctx, improcessing.stack, [["VIDEO", "GIF", "IMAGE"], ["VIDEO", "GIF", "IMAGE"]],
  File "main.py", line 443, in improcess
    urls = await imagesearch(ctx, len(allowedtypes))
  File "main.py", line 303, in imagesearch
    hm = await handlemessagesave(m)
  File "main.py", line 248, in handlemessagesave
    tenor = await fetch(
  File "/home/hex/Desktop/captionbot/improcessing.py", line 1430, in fetch
    async with session.get(url) as response:
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/aiohttp/client.py", line 1012, in __aenter__
    self._resp = await self._coro
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/aiohttp/client.py", line 504, in _request
    await resp.start(conn)
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/aiohttp/client_reqrep.py", line 847, in start
    message, payload = await self._protocol.read()  # type: ignore  # noqa
  File "/home/hex/.local/share/virtualenvs/captionbot-iutiqbOm/lib/python3.8/site-packages/aiohttp/streams.py", line 591, in read
    await self._waiter
aiohttp.client_exceptions.ClientOSError: [Errno 32] Broken pipe```

add animated effect commands

esmBot has commands like &spin and &globe and i'd like to make similar implementations into MediaForge. some other ideas are a version of $magick that increases the strength over the course of a gif/video

This will be implemented but not too soon due to its complexity with applying moving effects to already moving video.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.