Initial commit

master
Kuba Orlik 3 years ago
commit e612344d5e

@ -0,0 +1,35 @@
# Dziurkacz
Zestaw narzędzi pomagający wyciąć z pliku wideo te same fragmenty, które zostały wycięte z pliku audio.
## Wyamgania
- ffmpeg,
- Audacity,
- zx (https://github.com/google/zx)
## Instalacja
### Macro do Audacity
1. W Audacity utwórz makro z jednym krokiem.
2. Ustaw typ kroku: Nyquist Prompt
3. Kliknij `Edit`
4. Wklej do okienka dialogowego zawartość pliku `macro.ny` z niniejszego repozytorium
Następnie przypisz to makro do skrótu klawiaturowego (np. ctrl+d).
Odpalenie tego makro usunie zaznaczony fragment ścieżki i zapisze w labelce informacje o długości usuniętego fragmentu i jego pozycji w ścieżce
## Używanie
1. Otwórz plik dźwiękowy z video w Audacity i usuwaj fragmenty za pomocą makra opisanego powyżej.
2. Wyeksportuj wszystkie labelki do pliku tekstowego (export -> labels)
3. Uruchom `zx --quiet dziurkacz.mjs /ścieżka/do/pliku/video.mp4 /ścieżka/do/pliku/z/wyeskportowanymi/labelkami.txt`
Plik wynikowy znajdziesz w /tmp/dziurkacz/working.mp4

@ -0,0 +1,62 @@
import { extname } from "path";
const args = process.argv.slice(-2);
const video = args[0];
const labels = args[1];
const ext = extname(video);
const labels_contents = (await $`awk '{print $3, $4, $5}' < ${labels}`).stdout;
const FREQ = 48000;
const working_dir = "/tmp/dziurkacz";
const before_path = `${working_dir}/before${ext}`;
const after_path = `${working_dir}/after${ext}`;
const working_path = `${working_dir}/working${ext}`;
const vdlist = `${working_dir}/vdlist.txt`;
async function makeCut({ duration, start, end }) {
await Promise.all([
$`ffmpeg -i ${working_path} -to ${start} -c copy -an -y ${before_path}`,
$`ffmpeg -ss ${end} -i ${working_path} -c copy -an -y ${after_path}`,
]);
await Promise.all([
$`echo file ${before_path} > ${vdlist}`,
$`echo file ${after_path} >> ${vdlist}`,
]);
await $`ffmpeg -f concat -safe 0 -i ${vdlist} -c copy -y ${working_path} `;
}
await $`mkdir -p ${working_dir}`;
await $`cp -f ${video} ${working_path}`;
const cuts = labels_contents
.split(os.EOL)
.slice(0, -1)
.map((e) =>
e
.split(" ")
.slice(1)
.map((x) => parseFloat(x))
)
.map(([samples, start]) => ({
duration: samples / FREQ,
start,
end: start + samples / FREQ,
}));
// await makeCut(cuts[0]);
// await makeCut(cuts[1]);
for (const cut of cuts) {
await makeCut(cut);
}
console.log(
`Removed ${cuts
.map((e) => e.duration)
.reduce((a, b) => a + b, 0)
.toFixed(3)}s from video`
);

@ -0,0 +1,18 @@
(aud-do "AddLabel:")
(setf labels (car (cdr (car (aud-get-info "Labels")))))
(setf amount-of-labels (length labels))
(setf last-label (cdr labels))
(setf label-index (- amount-of-labels 1))
(setf label-index (cond ((= label-index -1) 0) (t label-index)))
(print label-index)
(aud-do-command "SetLabel" :text (format nil "~A ~A ~S" amount-of-labels LEN (get '*selection* 'start)) :label (- amount-of-labels 1) :start 0 :end 0)
(aud-do-command "Delete")
NIL
Loading…
Cancel
Save