# Error handling undefined URL: /docs/error-handling *** ## title: Error handling All endpoints return appropriate HTTP status codes: * 200: Success * 400: Bad Request (invalid parameters) * 404: File Not Found * 413: File Too Large * 500: Internal Server Error # How it works A breakdown of the service URL: /docs/how-it-works *** title: How it works description: A breakdown of the service --------------------------------------- ### The basics Right now the service has no authentication of any kind (it's a priority for me), but besides that, it works pretty similar to other services you might have encountered. You can upload a file, up to 500MB for now, for which you will get a `file_id` in the form of a nanoid. After this you can call the operation endpoints to schedule operations to be performed on said file. It currently has a limited set of operations, but I'm working to expand it. You can also chain operations by using the `/chain` endpoint. ### Metadata Regarding file metadata, it currently gets generated asynchronously after upload, so if you need it right after you have two options, you can poll the `/files/{file_id}` endpoint or call the `/meta/{file_id}` and get it directly. The `/meta/{file_id}` will not store it in DB though. ### How files are processed Each operation is stored in DB as a task, and tasks are acted on sequentially. If a task for a file fails, all the pending tasks left will be marked as unreachable to avoid unexpected results, as many tasks use a swap model for the files. The queue and operations will only swap the files on S3 if the operation and the cleanup tasks after complete successfully. Ideally the operation endpoints will fail if the operation can't be performed, if not, the tasks should have an error message. All operations currently have a timeout of 15 minutes, I used this as I have no idea really of how long operations could take, but wanted to make sure there was a limit, it can of course change in the future once I have more data. There is a `/status/{file_id}` endpoint that you can use to check when the file has been done processing. # Improvements undefined URL: /docs/improvements *** ## title: Improvements As I've saif before the service is quite simple and limited as it stands, I plan to add more customisation options for the tasks as well as better error handling and login, here's a list of them (I might've missed some): * allow users to specify codecs on operations * log the duration fo each operation * (I forgot as I was writing 😅, I'll update the list when I remember... if you have suggestions, create an issue on GH) # Welcome to Bunpeg A service to run FFmpeg commands via http URL: /docs *** title: Welcome to Bunpeg description: A service to run FFmpeg commands via http ------------------------------------------------------ ### Introduction Bunpeg is a service that allows you to run FFmpeg commands via http. The idea came from me trying to run FFmpeg on a Next.js project and failing miserably (skill issue ¯\_(ツ)\_/¯). So I decided to build a server that did it for me, and moving forward I could focus on building UIs which is what I like the most. However, this ended up being a fun project, forcing me to recall the little I knew about writing servers and to learn new stuff. I will continue to improve the server to add more operations and better configurations, if you have suggestions, write an issue, or better yet, a pull request. Anyway, thanks for stoping by! 👋 ### Note on AI Bunpeg doesn't have any AI features yet. I am thinking of a few ways to help you perform operations better, but that's for down the line, for now I want to focus on the operations. That being said, I know AI is everywhere, so I made it easier to feed these docs to your AI of choice. If you go to [/llm.txt](/llm.txt) you'll get the content of all the pages in one place. Also, if you only want to feed them one page, add **.mdx** to the url and you'll get the content as text. # Add audio undefined URL: /docs/operations/add-audio *** ## title: Add audio Add an audio track to a video. This one can be tricky if both video and audio don't have the same length. ```http POST /add-audio Content-Type: application/json { "videoFileId": "string", "audioFileId": "string", "outputFormat": "mp4" | "mkv" | "webm" | "mov" | "avi" } ``` ### Technical Details: * Swaps the video file * Smart codec selection based on output format: * MP4/MOV: AAC (192kbps) or copy if compatible * WebM: Opus (128kbps) or copy if compatible * MKV: Supports multiple codecs, defaults to AAC * AVI: MP3 or WAV * Uses `-shortest` flag to match video duration * Preserves video quality with `-c:v copy` # Bulk operations undefined URL: /docs/operations/bulk *** ## title: Bulk operations Create multiples of one operation on multiple files. This can be considered an inverse of the `/chain` endpoint ```http POST /bulk Content-Type: application/json { "fileIds": ["string"], "operation": { "type": "transcode" | "resize-video" | "trim" | "trim-end" | "extract-audio" | "remove-audio" | "extract-thumbnail", // Operation-specific parameters } } ``` ### Technical Details: * Operations can be executed parallel as they affect different files * Progress can be monitored via status endpoint * It doesn't include the `add-audio` or `merge-media` operations as these use a different payload # Chain operations undefined URL: /docs/operations/chain *** ## title: Chain operations Chain multiple operations on a file. ```http POST /chain Content-Type: application/json { "fileId": "string", "operations": [ { "type": "transcode" | "resize-video" | "trim" | "trim-end" | "extract-audio" | "remove-audio" | "extract-thumbnail", // Operation-specific parameters } ] } ``` ### Technical Details: * Operations are executed sequentially * Each operation maintains its own quality settings * Intermediate files are automatically cleaned up * Progress can be monitored via status endpoint * It doesn't include the `add-audio` or `merge-media` operations as these use a different payload # Extract audio undefined URL: /docs/operations/extract-audio *** ## title: Extract audio Extract audio from a video file. ```http POST /extract-audio Content-Type: application/json { "fileId": "string", "audioFormat": "mp3" | "m4a" | "aac" | "flac" | "wav" | "opus" } ``` ### Technical Details: * Generates a new file * Codec selection based on format: * MP3: libmp3lame with quality 2 * AAC/M4A: AAC codec at 192kbps * WAV: PCM 16-bit * FLAC: Native FLAC codec * Opus: libopus at 128kbps # Extract thumbnail undefined URL: /docs/operations/extract-thumbnail *** ## title: Extract thumbnail Extract a thumbnail from a video. ```http POST /extract-thumbnail Content-Type: application/json { "fileId": "string", "timestamp": "string", "imageFormat": "jpg" | "jpeg" | "png" | "webp" | "gif" | "avif" | "svg" } ``` ### Technical Details: * Generates a new file * Uses FFmpeg's `-vframes 1` for single frame extraction * High quality setting with `-q:v 2` * Supports multiple image formats * Frame-accurate timestamp selection # Merge videos undefined URL: /docs/operations/merge *** ## title: Merge videos Merge multiple media files. ```http POST /merge Content-Type: application/json { "fileIds": ["string", "string"], "outputFormat": "string" } ``` ### Technical Details: * Uses the first file (`fileIds[0]`) as the base, and swaps it with the results * Haven't tested it properly so I don't know what happens if some of the files are audio * Automatically detects and matches resolution * Preserves aspect ratio with padding * Uses complex filter chain for proper concatenation * Output encoding: * Video: H.264 (libx264) with fast preset, CRF 22 * Audio: AAC at 192kbps # Remove audio undefined URL: /docs/operations/remove-audio *** ## title: Remove audio Remove the audio track from a video. ```http POST /remove-audio Content-Type: application/json { "fileId": "string", "outputFormat": "mp4" | "mkv" | "webm" | "mov" | "avi" } ``` ### Technical Details: * Swaps the files * Uses FFmpeg's `-an` flag to strip audio * Preserves video quality * Fast operation as it only removes audio stream # Resize undefined URL: /docs/operations/resize *** ## title: Resize Resize a video to different a size, even though the numbers used are the same as the resolution this does not improve the resolution, so scaling a small res video will result in a bigger, pixelated video. ```http POST /resize-video Content-Type: application/json { "fileId": "string", "width": number, "height": number, "outputFormat": "mp4" | "mkv" | "webm" | "mov" | "avi" } ``` ### Technical Details: * Swaps the files * Uses FFmpeg's scale filter * Maintains aspect ratio * Output is encoded with libx264 codec # Transcode undefined URL: /docs/operations/transcode *** ## title: Transcode Convert a video to a different format. ```http POST /transcode Content-Type: application/json { "fileId": "string", "format": "mp4" | "mkv" | "webm" | "mov" | "avi" } ``` ### Technical Details: * Swaps the files * Uses FFmpeg's copy codec for faster transcoding * Preserves original video and audio quality # Trim end undefined URL: /docs/operations/trim-end *** ## title: Trim end Cut a segment from the end of a video. I'm not sure yet if this is very helpful, but it seemed so to me. I know this operation can be replicated with the `/trim`, but it seemed a bit harder that way. ```http POST /trim-end Content-Type: application/json { "fileId": "string", "duration": number, // time lapse to remove "outputFormat": "mp4" | "mkv" | "webm" | "mov" | "avi" } ``` ### Technical Details: * Swaps the files * Automatically calculates total duration * Uses FFmpeg's copy codec * Throws error if resulting video would be empty # Trim undefined URL: /docs/operations/trim *** ## title: Trim Trim a segment from a video. ```http POST /trim Content-Type: application/json { "fileId": "string", "start": number, "duration": number, "outputFormat": "mp4" | "mkv" | "webm" | "mov" | "avi" } ``` ### Technical Details: * Swaps the files * Uses FFmpeg's copy codec for fast trimming * Precise frame-accurate trimming * Preserves original quality