update
This commit is contained in:
parent
d81b69a2f1
commit
ca5215827e
8 changed files with 1102 additions and 107 deletions
|
@ -1,6 +1,8 @@
|
|||
FROM php:8.0-apache
|
||||
FROM php:apache-bookworm AS php-ffmpeg
|
||||
RUN apt-get update && apt-get -y install ffmpeg
|
||||
|
||||
FROM php-ffmpeg
|
||||
WORKDIR /var/www
|
||||
COPY src/ html/
|
||||
RUN mkdir uploads && chown -R www-data:www-data uploads
|
||||
RUN apt-get update && apt-get -y install ffmpeg
|
||||
EXPOSE 80/tcp
|
||||
|
|
354
src/index.php
354
src/index.php
|
@ -3,6 +3,9 @@
|
|||
|
||||
<head>
|
||||
<link rel="stylesheet" href="css/pico.min.css">
|
||||
<style>
|
||||
button {all: unset !important; cursor: pointer !important;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -14,31 +17,348 @@
|
|||
</hgroup>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<form action="upload.php" method="post" enctype="multipart/form-data">
|
||||
<form action="upload.php" method="post" enctype="multipart/form-data">
|
||||
|
||||
<main class="container">
|
||||
|
||||
<input id="picker" type="file" name="file">
|
||||
<div id="buttons" class="grid"></div>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<article id="audfxs" style="display: none;"><details><summary>Filters</summary>
|
||||
|
||||
<details role="list">
|
||||
<summary aria-haspopup="listbox">Effects</summary>
|
||||
<ul role="listbox">
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="tremolo" value="tremolo">
|
||||
Add Tremolo
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="vibrato" value="vibrato">
|
||||
Add Vibrato
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="speechnorm" value="speechnorm">
|
||||
Normalize Speech
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="loudnorm" value="loudnorm">
|
||||
Normalize Loudness
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="extrastereo" value="extrastereo">
|
||||
Boost stereo
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="asubboost" value="asubboost">
|
||||
Boost subwoofer
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="dialoguenhance" value="dialoguenhance">
|
||||
Enhance dialogue
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="earwax" value="earwax">
|
||||
Enhance headhpones (Earwax)
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="bs2b" value="bs2b">
|
||||
Enhance headhpones (Bauer)
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="flanger" value="flanger">
|
||||
Flanging effect
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="aphaser" value="aphaser">
|
||||
Phaser effect
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="anlmdn" value="anlmdn">
|
||||
Denoise
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="crystalizer" value="crystalizer">
|
||||
Sharpen Noise
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<details role="list">
|
||||
<summary aria-haspopup="listbox">Echo</summary>
|
||||
<ul role="listbox">
|
||||
<li>
|
||||
<label for="echo-none">
|
||||
<input id="echo-none" type="radio" name="echo" value="none" checked>
|
||||
None
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="echo-two">
|
||||
<input id="echo-two" type="radio" name="echo" value="two">
|
||||
Two instruments
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="echo-robot">
|
||||
<input id="echo-robot" type="radio" name="echo" value="robot">
|
||||
Like a robot
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="echo-mountains">
|
||||
<input id="echo-mountains" type="radio" name="echo" value="mountains">
|
||||
In the mountains
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="echo-more">
|
||||
<input id="echo-more" type="radio" name="echo" value="more">
|
||||
More mountains
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
</details></article>
|
||||
|
||||
<article id="picfxs" style="display: none;"><details><summary>Filters</summary>
|
||||
|
||||
<details role="list">
|
||||
<summary aria-haspopup="listbox">Rotate & Flip</summary>
|
||||
<ul role="listbox">
|
||||
<li>
|
||||
<label for="transforms-none">
|
||||
<input id="transforms-none" type="radio" name="transforms" value="none" checked>
|
||||
None
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="transforms-hflip">
|
||||
<input id="transforms-hflip" type="radio" name="transforms" value="hflip">
|
||||
Flip horizontally
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="transforms-vflip">
|
||||
<input id="transforms-vflip" type="radio" name="transforms" value="vflip">
|
||||
Flip vertically
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="transforms-clkrot">
|
||||
<input id="transforms-clkrot" type="radio" name="transforms" value="clkrot">
|
||||
Rotate 90° clockwise
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="transforms-aclkrot">
|
||||
<input id="transforms-aclkrot" type="radio" name="transforms" value="aclkrot">
|
||||
Rotate 90° anticlockwise
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="transforms-reverse">
|
||||
<input id="transforms-reverse" type="radio" name="transforms" value="reverse">
|
||||
Rotate 180°
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<details role="list">
|
||||
<summary aria-haspopup="listbox">Effects</summary>
|
||||
<ul role="listbox">
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="blur" value="blur">
|
||||
Blur
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="pixelize" value="pixelize">
|
||||
Pixelize
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="vignette" value="vignette">
|
||||
Vignette
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<details role="list">
|
||||
<summary aria-haspopup="listbox">Colorization</summary>
|
||||
<ul role="listbox">
|
||||
<li>
|
||||
<label for="colorize-none">
|
||||
<input id="colorize-none" type="radio" name="colorize" value="none" checked>
|
||||
None
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="colorize-bw">
|
||||
<input id="colorize-bw" type="radio" name="colorize" value="bw">
|
||||
Black & White
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="colorize-sepia">
|
||||
<input id="colorize-sepia" type="radio" name="colorize" value="sepia">
|
||||
Sepia
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
</details></article>
|
||||
|
||||
<article id="options" style="display: none;"></article>
|
||||
|
||||
</main>
|
||||
|
||||
</form>
|
||||
|
||||
<script>
|
||||
document.getElementById('picker').addEventListener('change', function(e) {
|
||||
if (e.target.files[0]) {
|
||||
fetch('json/conversions.json')
|
||||
const extension = e.target.files[0].name.split('.').pop();
|
||||
let optionsPath = "";
|
||||
switch (extension) {
|
||||
case "flac":
|
||||
case "ogg":
|
||||
case "oga":
|
||||
case "mka":
|
||||
case "caf":
|
||||
case "tta":
|
||||
case "mp1":
|
||||
case "mp2":
|
||||
case "mp3":
|
||||
case "spx":
|
||||
case "wv":
|
||||
case "opus":
|
||||
case "ts":
|
||||
optionsPath = "json/audio.json";
|
||||
break;
|
||||
case "jpg":
|
||||
case "jpeg":
|
||||
case "png":
|
||||
case "qoi":
|
||||
case "exr":
|
||||
case "webp":
|
||||
case "jxl":
|
||||
case "gif":
|
||||
case "jp2":
|
||||
case "j2k":
|
||||
case "j2c":
|
||||
case "avif":
|
||||
optionsPath = "json/picture.json";
|
||||
break;
|
||||
}
|
||||
fetch(optionsPath)
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
const fromExt = e.target.files[0].name.split('.').pop();
|
||||
const elButtons = document.getElementById("buttons");
|
||||
const elOptions = document.getElementById("options");
|
||||
|
||||
while (elButtons.firstChild) {
|
||||
elButtons.removeChild(elButtons.lastChild);
|
||||
}
|
||||
// Empty options area
|
||||
while (elOptions.firstChild) {
|
||||
elOptions.removeChild(elOptions.lastChild);
|
||||
}
|
||||
|
||||
for (toExt of json[fromExt]) {
|
||||
const elButton = document.createElement("input");
|
||||
elButton.setAttribute("type", "submit");
|
||||
elButton.setAttribute("name", "submit");
|
||||
elButton.setAttribute("value", toExt);
|
||||
elButtons.appendChild(elButton);
|
||||
for (encoding of json) {
|
||||
const elDetails = document.createElement("details");
|
||||
const elSummary = document.createElement("summary");
|
||||
const txSummary = document.createTextNode(encoding.abbr + (encoding.name ? " (" + encoding.name + ") " : " "));
|
||||
elSummary.appendChild(txSummary);
|
||||
elDetails.appendChild(elSummary);
|
||||
elOptions.appendChild(elDetails);
|
||||
|
||||
for (toExt of encoding.containers[0].extensions) {
|
||||
const txSpace = document.createTextNode(" ");
|
||||
const elKboard = document.createElement("kbd");
|
||||
const elButton = document.createElement("button");
|
||||
const txButton = document.createTextNode(toExt);
|
||||
elButton.setAttribute("value", encoding.abbr + "/" + toExt);
|
||||
elButton.setAttribute("name", "submit");
|
||||
elKboard.appendChild(txButton);
|
||||
elButton.appendChild(elKboard);
|
||||
elSummary.appendChild(elButton);
|
||||
elSummary.appendChild(txSpace);
|
||||
}
|
||||
|
||||
const elPList = document.createElement("p");
|
||||
const elList = document.createElement("ul");
|
||||
for (toCont of encoding.containers.slice(1)) {
|
||||
const elItem = document.createElement("li");
|
||||
const txSpace = document.createTextNode(" ");
|
||||
const txCont = document.createTextNode(toCont.name);
|
||||
elItem.appendChild(txCont);
|
||||
elItem.appendChild(txSpace);
|
||||
for (toExt of toCont.extensions) {
|
||||
const txSpace = document.createTextNode(" ");
|
||||
const elKboard = document.createElement("kbd");
|
||||
const elButton = document.createElement("button");
|
||||
const txButton = document.createTextNode(toExt);
|
||||
elButton.setAttribute("value", encoding.abbr + "/" + toExt);
|
||||
elButton.setAttribute("name", "submit");
|
||||
elKboard.appendChild(txButton);
|
||||
elButton.appendChild(elKboard);
|
||||
elItem.appendChild(elButton);
|
||||
elItem.appendChild(txSpace);
|
||||
}
|
||||
elList.appendChild(elItem);
|
||||
}
|
||||
|
||||
elPList.appendChild(elList);
|
||||
elDetails.appendChild(elPList);
|
||||
|
||||
const elDesc = document.createElement("p");
|
||||
const elUrl = document.createElement("a");
|
||||
elUrl.setAttribute("href", encoding.url);
|
||||
const txUrl = document.createTextNode("More information about the codec ↣");
|
||||
elDesc.appendChild(elUrl);
|
||||
elUrl.appendChild(txUrl);
|
||||
elDetails.appendChild(elDesc);
|
||||
|
||||
}
|
||||
document.getElementById("options").style.display = "block";
|
||||
switch (optionsPath) {
|
||||
case "json/picture.json":
|
||||
document.getElementById("picfxs").style.display = "block";
|
||||
document.getElementById("audfxs").style.display = "none";
|
||||
break;
|
||||
case "json/audio.json":
|
||||
document.getElementById("picfxs").style.display = "none";
|
||||
document.getElementById("audfxs").style.display = "block";
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
192
src/json/audio.json
Normal file
192
src/json/audio.json
Normal file
|
@ -0,0 +1,192 @@
|
|||
[
|
||||
{
|
||||
"abbr": "FLAC",
|
||||
"name": "Free Lossless Audio Codec",
|
||||
"url": "https://fr.wikipedia.org/wiki/Free_Lossless_Audio_Codec",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".flac"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Ogg",
|
||||
"extensions": [
|
||||
".ogg",
|
||||
".oga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Matroska",
|
||||
"extensions": [
|
||||
".mka"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "ALAC",
|
||||
"name": "Apple Lossless Audio Codec",
|
||||
"url": "https://en.wikipedia.org/wiki/Apple_Lossless_Audio_Codec",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Core Audio Format",
|
||||
"extensions": [
|
||||
".caf"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "Vorbis",
|
||||
"url": "https://en.wikipedia.org/wiki/Vorbis",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Ogg",
|
||||
"extensions": [
|
||||
".ogg",
|
||||
".oga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Matroska",
|
||||
"extensions": [
|
||||
".mka"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "WebM",
|
||||
"extensions": [
|
||||
".webm"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "TTA",
|
||||
"name": "True Audio",
|
||||
"url": "https://en.wikipedia.org/wiki/TTA_(codec)",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".tta"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "MP1",
|
||||
"name": "MPEG-1 Audio Layer I",
|
||||
"url": "https://en.wikipedia.org/wiki/MPEG-1_Audio_Layer_I",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".mp1"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "MP2",
|
||||
"name": "MPEG-1 Audio Layer II",
|
||||
"url": "https://en.wikipedia.org/wiki/MPEG-1_Audio_Layer_II",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".mp2"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "MP3",
|
||||
"name": "MPEG-1 Audio Layer III",
|
||||
"url": "https://en.wikipedia.org/wiki/MP3",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".mp3"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "Speex",
|
||||
"url": "https://en.wikipedia.org/wiki/Speex",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".spx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Ogg",
|
||||
"extensions": [
|
||||
".ogg",
|
||||
".oga"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "WavPack",
|
||||
"url": "https://en.wikipedia.org/wiki/WavPack",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Ogg",
|
||||
"extensions": [
|
||||
".wv"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Matroska",
|
||||
"extensions": [
|
||||
".mka"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "Opus",
|
||||
"url": "https://en.wikipedia.org/wiki/Opus_(audio_format)",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".opus"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Ogg",
|
||||
"extensions": [
|
||||
".ogg",
|
||||
".oga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Matroska",
|
||||
"extensions": [
|
||||
".mka"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "WebM",
|
||||
"extensions": [
|
||||
".webm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "MPEG-TS",
|
||||
"extensions": [
|
||||
".ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
109
src/json/audio.yaml
Normal file
109
src/json/audio.yaml
Normal file
|
@ -0,0 +1,109 @@
|
|||
- abbr: FLAC
|
||||
name: Free Lossless Audio Codec
|
||||
url: https://fr.wikipedia.org/wiki/Free_Lossless_Audio_Codec
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .flac
|
||||
- name: Ogg
|
||||
extensions:
|
||||
- .ogg
|
||||
- .oga
|
||||
- name: Matroska
|
||||
extensions:
|
||||
- .mka
|
||||
|
||||
- abbr: ALAC
|
||||
name: Apple Lossless Audio Codec
|
||||
url: https://en.wikipedia.org/wiki/Apple_Lossless_Audio_Codec
|
||||
containers:
|
||||
- name: Core Audio Format
|
||||
extensions:
|
||||
- .caf
|
||||
|
||||
- abbr: Vorbis
|
||||
url: https://en.wikipedia.org/wiki/Vorbis
|
||||
containers:
|
||||
- name: Ogg
|
||||
extensions:
|
||||
- .ogg
|
||||
- .oga
|
||||
- name: Matroska
|
||||
extensions:
|
||||
- .mka
|
||||
- name: WebM
|
||||
extensions:
|
||||
- .webm
|
||||
|
||||
- abbr: TTA
|
||||
name: True Audio
|
||||
url: https://en.wikipedia.org/wiki/TTA_(codec)
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .tta
|
||||
|
||||
- abbr: MP1
|
||||
name: MPEG-1 Audio Layer I
|
||||
url: https://en.wikipedia.org/wiki/MPEG-1_Audio_Layer_I
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .mp1
|
||||
|
||||
- abbr: MP2
|
||||
name: MPEG-1 Audio Layer II
|
||||
url: https://en.wikipedia.org/wiki/MPEG-1_Audio_Layer_II
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .mp2
|
||||
|
||||
- abbr: MP3
|
||||
name: MPEG-1 Audio Layer III
|
||||
url: https://en.wikipedia.org/wiki/MP3
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .mp3
|
||||
|
||||
- abbr: Speex
|
||||
url: https://en.wikipedia.org/wiki/Speex
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .spx
|
||||
- name: Ogg
|
||||
extensions:
|
||||
- .ogg
|
||||
- .oga
|
||||
|
||||
- abbr: WavPack
|
||||
url: https://en.wikipedia.org/wiki/WavPack
|
||||
containers:
|
||||
- name: Ogg
|
||||
extensions:
|
||||
- .wv
|
||||
- name: Matroska
|
||||
extensions:
|
||||
- .mka
|
||||
|
||||
- abbr: Opus
|
||||
url: https://en.wikipedia.org/wiki/Opus_(audio_format)
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .opus
|
||||
- name: Ogg
|
||||
extensions:
|
||||
- .ogg
|
||||
- .oga
|
||||
- name: Matroska
|
||||
extensions:
|
||||
- .mka
|
||||
- name: WebM
|
||||
extensions:
|
||||
- .webm
|
||||
- name: MPEG-TS
|
||||
extensions:
|
||||
- .ts
|
|
@ -1,84 +0,0 @@
|
|||
{
|
||||
"jpeg": [
|
||||
"jp2",
|
||||
"webp",
|
||||
"png",
|
||||
"gif"
|
||||
],
|
||||
"jp2": [
|
||||
"jpeg",
|
||||
"webp",
|
||||
"png",
|
||||
"gif"
|
||||
],
|
||||
"webp": [
|
||||
"jpeg",
|
||||
"jp2",
|
||||
"png",
|
||||
"gif"
|
||||
],
|
||||
"png": [
|
||||
"jpeg",
|
||||
"jp2",
|
||||
"webp",
|
||||
"gif"
|
||||
],
|
||||
"gif": [
|
||||
"jpeg",
|
||||
"jp2",
|
||||
"webp",
|
||||
"png"
|
||||
],
|
||||
|
||||
"av1": [
|
||||
"mkv",
|
||||
"webm",
|
||||
"ogv"
|
||||
],
|
||||
"mkv": [
|
||||
"av1",
|
||||
"webm",
|
||||
"ogv"
|
||||
],
|
||||
"webm": [
|
||||
"av1",
|
||||
"mkv",
|
||||
"ogv"
|
||||
],
|
||||
"ogv": [
|
||||
"av1",
|
||||
"mkv",
|
||||
"webm"
|
||||
],
|
||||
|
||||
"alac": [
|
||||
"flac",
|
||||
"mp3",
|
||||
"ogg",
|
||||
"wav"
|
||||
],
|
||||
"flac": [
|
||||
"alac",
|
||||
"mp3",
|
||||
"ogg",
|
||||
"wav"
|
||||
],
|
||||
"mp3": [
|
||||
"alac",
|
||||
"flac",
|
||||
"ogg",
|
||||
"wav"
|
||||
],
|
||||
"ogg": [
|
||||
"alac",
|
||||
"flac",
|
||||
"mp3",
|
||||
"wav"
|
||||
],
|
||||
"wav": [
|
||||
"alac",
|
||||
"flac",
|
||||
"ogg",
|
||||
"mp3"
|
||||
]
|
||||
}
|
118
src/json/picture.json
Normal file
118
src/json/picture.json
Normal file
|
@ -0,0 +1,118 @@
|
|||
[
|
||||
{
|
||||
"abbr": "JPEG",
|
||||
"name": "Joint Photographic Experts Group",
|
||||
"url": "https://en.wikipedia.org/wiki/JPEG",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".jpg",
|
||||
".jpeg"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "PNG",
|
||||
"name": "Portable Network Graphics",
|
||||
"url": "https://en.wikipedia.org/wiki/JPEG",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".png"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "QOI",
|
||||
"name": "Quite OK Image Format",
|
||||
"url": "https://en.wikipedia.org/wiki/QOI_(image_format)",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".qoi"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "OpenEXR",
|
||||
"url": "https://en.wikipedia.org/wiki/OpenEXR",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".exr"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "WebP",
|
||||
"url": "https://en.wikipedia.org/wiki/WebP",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".webp"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "JPEG XL",
|
||||
"url": "https://en.wikipedia.org/wiki/JPEG_XL",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".jxl"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "GIF",
|
||||
"name": "Graphics Interchange Format",
|
||||
"url": "https://en.wikipedia.org/wiki/GIF",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".gif"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "JPEG 2000",
|
||||
"url": "https://en.wikipedia.org/wiki/JPEG_2000",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".jp2",
|
||||
".j2k",
|
||||
".j2c"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"abbr": "AVIF",
|
||||
"name": "AV1 Image File Format",
|
||||
"url": "https://en.wikipedia.org/wiki/JPEG_2000",
|
||||
"containers": [
|
||||
{
|
||||
"name": "Native",
|
||||
"extensions": [
|
||||
".avif"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
70
src/json/picture.yaml
Normal file
70
src/json/picture.yaml
Normal file
|
@ -0,0 +1,70 @@
|
|||
- abbr: JPEG
|
||||
name: Joint Photographic Experts Group
|
||||
url: https://en.wikipedia.org/wiki/JPEG
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .jpg
|
||||
- .jpeg
|
||||
|
||||
- abbr: PNG
|
||||
name: Portable Network Graphics
|
||||
url: https://en.wikipedia.org/wiki/JPEG
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .png
|
||||
|
||||
- abbr: QOI
|
||||
name: Quite OK Image Format
|
||||
url: https://en.wikipedia.org/wiki/QOI_(image_format)
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .qoi
|
||||
|
||||
- abbr: OpenEXR
|
||||
url: https://en.wikipedia.org/wiki/OpenEXR
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .exr
|
||||
|
||||
- abbr: WebP
|
||||
url: https://en.wikipedia.org/wiki/WebP
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .webp
|
||||
|
||||
- abbr: JPEG XL
|
||||
url: https://en.wikipedia.org/wiki/JPEG_XL
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .jxl
|
||||
|
||||
- abbr: GIF
|
||||
name: Graphics Interchange Format
|
||||
url: https://en.wikipedia.org/wiki/GIF
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .gif
|
||||
|
||||
- abbr: JPEG 2000
|
||||
url: https://en.wikipedia.org/wiki/JPEG_2000
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .jp2
|
||||
- .j2k
|
||||
- .j2c
|
||||
|
||||
- abbr: AVIF
|
||||
name: AV1 Image File Format
|
||||
url: https://en.wikipedia.org/wiki/JPEG_2000
|
||||
containers:
|
||||
- name: Native
|
||||
extensions:
|
||||
- .avif
|
276
src/upload.php
276
src/upload.php
|
@ -1,7 +1,8 @@
|
|||
<?php
|
||||
|
||||
$fromExt = strtolower(pathinfo($_FILES["file"]["name"])['extension']);
|
||||
$toExt = $_POST["submit"];
|
||||
$toMIME = $_POST["submit"];
|
||||
$toExt = "";
|
||||
$jobId = bin2hex(random_bytes(16));
|
||||
|
||||
chdir('/var/www/uploads/');
|
||||
|
@ -9,12 +10,279 @@ mkdir($jobId);
|
|||
chdir($jobId);
|
||||
move_uploaded_file($_FILES["file"]["tmp_name"], "upload.$fromExt");
|
||||
|
||||
exec("ffmpeg -y -i upload.$fromExt output.$toExt");
|
||||
$filter = array();
|
||||
$afilter = array();
|
||||
|
||||
if (isset($_POST["blur"])) {
|
||||
array_push($filter,"gblur");
|
||||
}
|
||||
if (isset($_POST["pixelize"])) {
|
||||
array_push($filter,"pixelize");
|
||||
}
|
||||
if (isset($_POST["vignette"])) {
|
||||
array_push($filter,"vignette");
|
||||
}
|
||||
if (isset($_POST["tremolo"])) {
|
||||
array_push($afilter,"tremolo");
|
||||
}
|
||||
if (isset($_POST["vibrato"])) {
|
||||
array_push($afilter,"vibrato");
|
||||
}
|
||||
if (isset($_POST["speechnorm"])) {
|
||||
array_push($afilter,"speechnorm");
|
||||
}
|
||||
if (isset($_POST["loudnorm"])) {
|
||||
array_push($afilter,"loudnorm");
|
||||
}
|
||||
if (isset($_POST["extrastereo"])) {
|
||||
array_push($afilter,"extrastereo");
|
||||
}
|
||||
if (isset($_POST["asubboost"])) {
|
||||
array_push($afilter,"asubboost");
|
||||
}
|
||||
if (isset($_POST["dialoguenhance"])) {
|
||||
array_push($afilter,"dialoguenhance");
|
||||
}
|
||||
if (isset($_POST["earwax"])) {
|
||||
array_push($afilter,"earwax");
|
||||
}
|
||||
if (isset($_POST["bs2b"])) {
|
||||
array_push($afilter,"bs2b");
|
||||
}
|
||||
if (isset($_POST["chorus"])) {
|
||||
array_push($afilter,"aecho=0.8:0.9:1000|1800:0.3|0.25");
|
||||
}
|
||||
if (isset($_POST["flanger"])) {
|
||||
array_push($afilter,"flanger");
|
||||
}
|
||||
if (isset($_POST["aphaser"])) {
|
||||
array_push($afilter,"aphaser");
|
||||
}
|
||||
if (isset($_POST["crystalizer"])) {
|
||||
array_push($afilter,"crystalizer");
|
||||
}
|
||||
if (isset($_POST["anlmdn"])) {
|
||||
array_push($afilter,"anlmdn");
|
||||
}
|
||||
|
||||
switch($_POST["transforms"]) {
|
||||
case "hflip":
|
||||
array_push($filter, "hflip");
|
||||
break;
|
||||
case "vflip":
|
||||
array_push($filter, "vflip");
|
||||
break;
|
||||
case "clkrot":
|
||||
array_push($filter, "rotate=PI/2");
|
||||
break;
|
||||
case "aclkrot":
|
||||
array_push($filter, "rotate=-PI/2");
|
||||
break;
|
||||
case "reverse":
|
||||
array_push($filter, "rotate=PI");
|
||||
break;
|
||||
}
|
||||
|
||||
switch($_POST["colorize"]) {
|
||||
case "bw":
|
||||
array_push($filter,"colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3");
|
||||
break;
|
||||
case "sepia":
|
||||
array_push($filter,"colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131");
|
||||
break;
|
||||
}
|
||||
|
||||
switch($_POST["echo"]) {
|
||||
case "two":
|
||||
array_push($afilter,"aecho=0.8:0.88:60:0.4");
|
||||
break;
|
||||
case "robot":
|
||||
array_push($afilter,"aecho=0.8:0.88:6:0.4");
|
||||
break;
|
||||
case "mountains":
|
||||
array_push($afilter,"aecho=0.8:0.9:1000:0.3");
|
||||
break;
|
||||
case "more":
|
||||
array_push($afilter,"aecho=0.8:0.9:1000|1800:0.3|0.25");
|
||||
break;
|
||||
}
|
||||
|
||||
$filter_str = implode(',',$filter);
|
||||
$filter_str = empty($filter_str) ? "" : "-vf '$filter_str'";
|
||||
|
||||
$afilter_str = implode(',',$afilter);
|
||||
$afilter_str = empty($afilter_str) ? "" : "-af '$afilter_str'";
|
||||
|
||||
switch($toMIME) {
|
||||
case "FLAC/.flac":
|
||||
$toExt = "flac";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec flac $afilter_str output.$toExt");
|
||||
break;
|
||||
case "FLAC/.ogg":
|
||||
$toExt = "ogg";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec flac $afilter_str output.$toExt");
|
||||
break;
|
||||
case "FLAC/.oga":
|
||||
$toExt = "oga";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec flac $afilter_str output.$toExt");
|
||||
break;
|
||||
case "FLAC/.mka":
|
||||
$toExt = "mka";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec flac $afilter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "ALAC/.caf":
|
||||
$toExt = "caf";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec alac $afilter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "WavPack/.wv":
|
||||
$toExt = "wv";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec wavpack $afilter_str output.$toExt");
|
||||
break;
|
||||
case "WavPack/.mka":
|
||||
$toExt = "mka";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec wavpack $afilter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "Vorbis/.ogg":
|
||||
$toExt = "ogg";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec vorbis $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
case "Vorbis/.oga":
|
||||
$toExt = "oga";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec vorbis $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
case "Vorbis/.mka":
|
||||
$toExt = "mka";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec vorbis $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
case "Vorbis/.webm":
|
||||
$toExt = "webm";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec vorbis $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
|
||||
case "Speex/.spx":
|
||||
$toExt = "spx";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec speex $afilter_str output.$toExt");
|
||||
break;
|
||||
case "Speex/.ogg":
|
||||
$toExt = "ogg";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec speex $afilter_str output.$toExt");
|
||||
break;
|
||||
case "Speex/.oga":
|
||||
$toExt = "oga";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec speex $afilter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "MP1/.mp1":
|
||||
$toExt = "mp1";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec mp1 $afilter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "MP2/.mp2":
|
||||
$toExt = "mp2";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec mp2 $afilter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "MP3/.mp3":
|
||||
$toExt = "mp3";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec mp3 $afilter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "TTA/.tta":
|
||||
$toExt = "tta";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec tta $afilter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "Opus/.opus":
|
||||
$toExt = "opus";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec opus $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
case "Opus/.ogg":
|
||||
$toExt = "ogg";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec opus $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
case "Opus/.oga":
|
||||
$toExt = "oga";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec opus $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
case "Opus/.mka":
|
||||
$toExt = "mka";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec opus $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
case "Opus/.webm":
|
||||
$toExt = "webm";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec opus $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
case "Opus/.ts":
|
||||
$toExt = "ts";
|
||||
exec("ffmpeg -y -i upload.$fromExt -acodec opus $afilter_str -strict -2 output.$toExt");
|
||||
break;
|
||||
|
||||
case "JPEG/.jpg":
|
||||
$toExt = "jpg";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec mjpeg $filter_str output.$toExt");
|
||||
break;
|
||||
case "JPEG/.jpeg":
|
||||
$toExt = "jpeg";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec mjpeg $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "PNG/.png":
|
||||
$toExt = "png";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec png $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "QOI/.qoi":
|
||||
$toExt = "qoi";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec qoi $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "OpenEXR/.exr":
|
||||
$toExt = "exr";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec exr $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "WebP/.webp":
|
||||
$toExt = "webp";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec webp $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "JPEG XL/.jxl":
|
||||
$toExt = "jxl";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec jpegxl $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "GIF/.gif":
|
||||
$toExt = "gif";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec gif $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "JPEG 2000/.jp2":
|
||||
$toExt = "jp2";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec jpeg2000 $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "JPEG 2000/.j2k":
|
||||
$toExt = "j2k";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec jpeg2000 $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "JPEG 2000/.j2c":
|
||||
$toExt = "j2c";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec jpeg2000 $filter_str output.$toExt");
|
||||
break;
|
||||
|
||||
case "AVIF/.avif":
|
||||
$toExt = "avif";
|
||||
exec("ffmpeg -y -i upload.$fromExt -vcodec av1 $filter_str output.$toExt");
|
||||
break;
|
||||
}
|
||||
|
||||
header("Cache-Control: public");
|
||||
header("Content-Description: File Transfer");
|
||||
header("Content-D6escription: File Transfer");
|
||||
header("Content-Disposition: attachment; filename=output.$toExt");
|
||||
header("Content-Type: application/jpeg");
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
|
||||
readfile("/var/www/uploads/$jobId/output.$toExt");
|
||||
|
|
Loading…
Reference in a new issue