Skip to content
Extraits de code Groupes Projets
Valider cdb1114e rédigé par Sting's avatar Sting
Parcourir les fichiers

Merge branch 'windows-compat' into 'master'

Windows compat

See merge request !6
parents a204811e 3482b96f
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!6Windows compat
include requirements.txt
include README.md
include preprocess_media.sh
recursive-include autokara *
......@@ -14,24 +14,22 @@ All other python modules can be installed directly through PIP, see next section
## Install
### Linux
Using a virtual environment is strongly recommended (but not mandatory if you know what you're doing) :
```bash
$ python -m venv env # create the virtual environment, do it once
$ source env/bin/activate # use the virtual environement
python -m venv env # create the virtual environment, do it once
source env/bin/activate # use the virtual environement
# To exit the virtual environment
$ deactivate
deactivate
```
The simplest way to install Autokara is through PIP.
```bash
# Using HTTPS
$ pip install git+https://git.iiens.net/bakaclub/autokara.git
pip install git+https://git.iiens.net/bakaclub/autokara.git
# Or SSH
$ pip install git+ssh://git@git.iiens.net:bakaclub/autokara.git
pip install git+ssh://git@git.iiens.net:bakaclub/autokara.git
```
Or you can clone the repo and use `pip install <repo_directory>` if you prefer.
......@@ -39,12 +37,9 @@ Or you can clone the repo and use `pip install <repo_directory>` if you prefer.
To use the custom phonetic mappings for Japanese Romaji and other non-English languages, you need to update manually (for now) the g2p DB (within the venv):
```bash
$ autokara-gen-lang
autokara-gen-lang
```
### Windows
Still working on that...
## Configuration
......@@ -61,32 +56,37 @@ This new file has priority over the default one, which is used only as fallback.
To use Autokara, you need :
- A media file of the song (video, or pre-extracted vocals)
- An ASS file with the lyrics, split by syllable
- An ASS file with the lyrics, split by syllable (you can use the [Auto-Split](https://docs.karaokes.moe/aegisub/auto-split.lua) in Aegisub, but doing it manually may yield better results)
To execute AutoKara on a MKV video file and an ASS file containing the lyrics (ASS will be overwritten):
```bash
$ autokara video.mkv lyrics.ass
autokara video.mkv lyrics.ass
```
To output to a different file (and keep the original) :
```bash
$ autokara video.mkv lyrics.ass -o output.ass
autokara video.mkv lyrics.ass -o output.ass
```
To execute AutoKara on a (pre-extracted) WAV (or OGG, MP3, ...) vocals file, pass the `--vocals` flag :
```bash
$ autokara vocals.wav output.ass --vocals
autokara vocals.wav lyrics.ass --vocals
```
To use a phonetic transcription optimized for a specific language, use `--lang` (or `-l`) :
To use a phonetic transcription optimized for a specific language, use `--lang` (or `-l`). Default is Japanese Romaji.
You can also specify a specific language for uppercase words (default is set in your config file) :
```bash
$ autokara vocals.wav output.ass --lang jp
# Use french transcription
autokara video.mkv lyrics.ass --lang fr
# Use english transcription, but treat all uppercase words as french :
autokara video.mkv lyrics.ass --lang en --uppercase-lang fr
```
Available languages options are :
```
jp : Japanese Romaji (default)
en : English
jp : Japanese Romaji (base default)
en : English (uppercase default)
fr : French
fi : Finnish
da : Danish
......@@ -94,36 +94,35 @@ da : Danish
Full help for all options is available with :
```bash
$ autokara -h
autokara -h
```
## Useful scripts
To only extract .wav audio from a MKV file :
```bash
$ ./extractWav.sh source_video output_audio
```
### Manual preprocessing
To only extract .ass sub file from a MKV file :
```bash
$ ./extractAss.sh source_video output_subs
```
Use `autokara-preprocess` if you want to manually preprocess video/lyrics in advance :
To only separate vocals from instruments in an audio file :
```bash
demucs --two-stems=vocals -o output_folder audio_file.wav
```
# Extract vocals from video :
autokara-preprocess --vocals video_file output_folder/
Batch preprocessing (vocals + ASS extraction) of all videos in a directory :
```bash
$ ./preprocess_media.sh video_folder output_folder
# Extract ASS file from a MKV containing a subtitle track :
autokara-preprocess --lyrics video_file output_file.ass
# Do both at once :
autokara-preprocess --full video_file output_folder/
```
A visualization tool, mainly intended for debug.
Does the same as autokara.py, but instead of writing to a file, plots a graphic with onset times, spectrogram, probability curves,...
Does not work on video files, only separated vocals audio files
Then you can use Autokara on the extracted files with the `--vocals` flag.
### Sound and onsets plotting
A visualization tool, mainly intended for debug or curious people.
Does the same as `autokara`, but instead of writing to a file, plots a graphic with syllable onset times, spectrogram, probability curves,...
Does not work on video files, only separated vocals audio files :
```bash
$ autokara-plot vocals.wav lyrics.ass
autokara-plot vocals.wav lyrics.ass
```
......
......@@ -3,11 +3,14 @@ import argparse
import demucs.separate
import subprocess
import shlex
import shutil
from pathlib import Path
from configparser import ConfigParser
from .autosyl.assUtils import AssWriter, getSyls, getHeader
from .autosyl.segment import segment
from .preprocess.audio import *
from .preprocess.lyrics import *
......@@ -25,6 +28,7 @@ def main(opts=None):
args = parser.parse_args(opts)
ass_file = args.ass_file
source_file = args.source_file
verbose = args.verbose
here = Path(__file__).parent
......@@ -54,16 +58,14 @@ def main(opts=None):
basename = Path(args.source_file).stem
audio_file = f"{media_dir:s}/audio/{basename:s}.wav"
subprocess.call(shlex.split(f'{str(here)}/extractWav.sh "{args.source_file:s}" "{audio_file}"'))
extract_audio(source_file, output_file=audio_file)
Path(f"{media_dir:s}/vocals").mkdir(parents=True, exist_ok=True)
output_folder = f"{media_dir:s}/vocals"
print("Isolating vocals...")
# Not working, don't know why
# demucs.separate.main(shlex.split('--two-stems vocals -o "%s" "%s"' % (output_folder, audio_file)))
subprocess.call(shlex.split(f'demucs --two-stems vocals -o "{output_folder:s}" "{audio_file:s}"'))
extract_vocals(audio_file, output_folder)
vocals_file = f"{media_dir:s}/vocals/htdemucs/{basename:s}/vocals.wav"
else:
......@@ -92,6 +94,11 @@ def main(opts=None):
writer.writeSyls(syls, line_meta)
writer.closeAss()
# clean up
if not args.vocals:
shutil.rmtree(f'{media_dir:s}/vocals/htdemucs/{basename:s}')
Path(audio_file).unlink(missing_ok=True)
if __name__ == "__main__":
main()
......
......@@ -32,6 +32,7 @@ def getSyls(ass_file):
LINES_KARA = re.compile(r"(?:Comment|Dialogue):.*(\d+:\d{2}:\d{2}.\d{2}),(\d+:\d{2}:\d{2}.\d{2}),([^,]*),([^,]*),(\d+),(\d+),(\d+),(?:(?!fx|template|code)\w)*,(.*)\n")
RGX_TAGS = re.compile(r"\{\\k(\d+)\}([^\{\n\r]*)")
for line in LINES_KARA.findall(CONTENT):
if line[7].strip() != "":
syl_line = []
lastTime = dateToTime(line[0])
syl_line_index = 0
......
#!/bin/bash
##########################################################################################################
#
# COMMAND : extractAss.sh
#
# AUTHOR : Kubat
#
# DESCRIPTION : CLI tool to extract subtitles from .mkv files
#
# USE : ./extractAss.sh fileInput.mkv fileOutput.ass
#
# REQUIREMENTS : Have FFMPEG and SoX installed (for audio/video decoding)
#
#
##########################################################################################################
USAGE_MESSAGE="usage : $0 fileInput.mkv fileOutput.ass"
if [ $# != 2 ]
then
echo $USAGE_MESSAGE
exit 1
fi
if ! [[ "$1" =~ .mkv$ ]] || ! [[ "$2" =~ .ass$ ]]
then
echo $USAGE_MESSAGE
exit 1
fi
# get the subtitles track id
ID=$(mkvmerge --identify "$1" | sed -n 's/Track ID \([[:digit:]]*\).*subtitles.*/\1/p')
mkvextract tracks "$1" "$ID":"$2"
#!/bin/bash
##########################################################################################################
#
# COMMAND : extractWav.sh
#
# AUTHOR : Sting
#
# DESCRIPTION : CLI tool to extract audio from .mkv files and convert it to 1-channel WAV files
# Currently supported formats :
# - Video : .mkv files only, any codec supported by FFMPEG
# - Audio : AAC, FLAC, DTS, AC3, MP3 (MPEG), OPUS, VORBIS
#
# USE : ./extractWav.sh source_folder destination_folder
#
# REQUIREMENTS : Have FFMPEG and SoX installed (for audio/video decoding)
#
#
##########################################################################################################
USAGE_MESSAGE="usage : $0 source_file dest_file"
if [ $# != 2 ]; then
echo $USAGE_MESSAGE; exit 1;
fi
filename=$1
dest_file=$2
echo $filename
echo $dest_file
[ -e "$filename" ] || continue
name=${filename##*/}
base=${name%.mkv}
codecLine=$(mkvinfo "$filename" | grep " A_")
regex=".*A_([A-Z0-9]+).*"
[[ $codecLine =~ $regex ]]
codec=${BASH_REMATCH[1]}
case $codec in
"AAC")
extension="m4a"
;;
"FLAC")
extension="flac"
;;
"VORBIS")
extension="ogg"
;;
"MPEG")
extension="mp3"
;;
"AC3")
extension="ac3"
;;
"EAC3")
extension="eac3"
;;
"DTS")
extension="dts"
;;
"OPUS")
extension="opus"
;;
*)
extension=""
;;
esac
ffmpeg -i "$filename" -acodec copy -vn "$base.$extension" && \
ffmpeg -i "$base.$extension" "$base.wav" && \
#sox "$2/$base.stereo.wav" "$2/$base.wav" remix - && \
#rm "$2/$base.stereo.wav" && \
rm "$base.$extension"
mv "$base.wav" "$2"
import sys
import argparse
import demucs.separate
import subprocess
import shlex
from pathlib import Path
import shutil
def extract_audio(source_file, output_file=None):
if not output_file:
out_path = Path(source_file).with_suffix(".wav")
else:
out_path = output_file
subprocess.call(shlex.split(f'ffmpeg -i "{source_file:s}" -vn "{out_path:s}"'))
return str(out_path)
def extract_vocals(source_file, output_folder):
subprocess.call(shlex.split(f'demucs --two-stems vocals -o "{output_folder:s}" "{source_file:s}"'))
def preprocess_video(source_file, output_folder=None, media_dir="."):
Path(media_dir + "/audio").mkdir(parents=True, exist_ok=True)
basename = Path(source_file).stem
audio_file = f"{media_dir:s}/audio/{basename:s}.wav"
print("Extracting audio from video file...")
extract_audio(source_file, audio_file)
if not output_folder:
Path(f"{media_dir:s}/vocals").mkdir(parents=True, exist_ok=True)
output_folder = f"{media_dir:s}/vocals"
print("Isolating vocals...")
extract_vocals(audio_file, output_folder)
subprocess.call(shlex.split(f'ffmpeg -i "{output_folder:s}/htdemucs/{basename:s}/vocals.wav" "{output_folder:s}/vocals.ogg"'))
shutil.rmtree(f'{output_folder:s}/htdemucs/{basename:s}')
Path(audio_file).unlink(missing_ok=True)
import sys
import argparse
import subprocess
import shlex
from pathlib import Path
import re
def extract_subtitles(source_file, output_file=None):
if not output_file:
out_path = Path(source_file).with_suffix(".ass")
else:
out_path = output_file
data = subprocess.run(f'mkvmerge --identify "{source_file:s}"', capture_output=True, shell=True, text=True)
RGX_TRACK = re.compile(r"Track ID (\d+): subtitles")
matches = RGX_TRACK.findall(data.stdout)
track_id = matches[0][0]
subprocess.call(shlex.split(f'mkvextract "{source_file:s}" tracks "{track_id:s}":"{out_path:s}"'))
\ No newline at end of file
from .preprocess.audio import *
from .preprocess.lyrics import *
import sys
import argparse
from configparser import ConfigParser
def main(opts=None):
parser = argparse.ArgumentParser(description='Script to prepare media for Autokara - extract vocals and lyrics from video')
parser.add_argument("--vocals", action="store_true", help="Perform vocals extraction on source file")
parser.add_argument("--lyrics", action="store_true", help="Perform ASS extraction on source file, if it has a subtitle track")
parser.add_argument("--full", action="store_true", help="Extract both vocals and lyrics")
parser.add_argument("source_file", type=str, help="The video/audio file to preprocess")
parser.add_argument("output_file", type=str, help="If extracting lyrics, the ASS output file. If extracting vocals or both, the output folder for separated tracks")
args = parser.parse_args(opts)
here = Path(__file__).parent
config = ConfigParser()
config.read([
str(here / "default.conf"), # Default config file
str(Path().home()/ ".config" / "autokara"/ "autokara.conf") # User config file
])
media_dir = config['Media']['media_dir']
source_file = args.source_file
output_file = args.output_file
if args.full or (args.vocals and args.lyrics) or (not args.full and not args.vocals and not args.lyrics):
preprocess_video(source_file, output_folder=output_file, media_dir=media_dir)
extract_subtitles(source_file, output_file=f'{output_file:s}/vocals.ass')
elif args.vocals:
preprocess_video(source_file, output_folder=output_file, media_dir=media_dir)
elif args.lyrics:
extract_subtitles(source_file, output_file=output_file)
if __name__ == "__main__":
main()
#!/bin/bash
##########################################################################################################
#
# COMMAND : preprocess_media.sh
#
# AUTHOR : Sting
#
# DESCRIPTION : CLI tool to batch extract ASS lyrics and vocals from a video folder
#
# USE : ./preprocess_media.sh input_folder output_folder
#
# REQUIREMENTS : FFMPEG, Demucs, extractAss and extractWav
#
#
##########################################################################################################
USAGE_MESSAGE="usage : $0 video_folder train_folder"
if [ $# != 2 ]; then
echo $USAGE_MESSAGE; exit 1;
fi
video_folder=$1
train_folder=$2
for filename in "$video_folder"/*.mkv; do
name=${filename##*/}
base=${name%.mkv}
mkdir -p "$train_folder/$base"
extractWav.sh "$filename" "$train_folder/$base/$base.wav"
demucs --two-stems vocals -o "$train_folder/$base" "$train_folder/$base/$base.wav"
rm "$train_folder/$base/$base.wav"
ffmpeg -i "$train_folder/$base/htdemucs/$base/vocals.wav" "$train_folder/$base/vocals.ogg"
rm -r "$train_folder/$base/htdemucs"
extractAss.sh "$filename" "$train_folder/$base/vocals.ass"
done;
\ No newline at end of file
......@@ -50,14 +50,11 @@ setup(
entry_points={
'console_scripts': ['autokara=autokara.autokara:main',
'autokara-plot=autokara.plot_syls:main',
'autokara-gen-lang=autokara.update_lang_db:main'
'autokara-gen-lang=autokara.update_lang_db:main',
'autokara-preprocess=autokara.preprocess_media:main'
],
},
scripts=[
'autokara/extractAss.sh',
'autokara/extractWav.sh',
'preprocess_media.sh'
],
scripts=[],
license='MIT License',
classifiers=[
# Trove classifiers
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter