Initial commit
This commit is contained in:
commit
e612344d5e
35
README.md
Normal file
35
README.md
Normal file
@ -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
|
62
dziurkacz.mjs
Normal file
62
dziurkacz.mjs
Normal file
@ -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`
|
||||||
|
);
|
18
macro.ny
Normal file
18
macro.ny
Normal file
@ -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…
Reference in New Issue
Block a user