Checkpoint 2
This commit is contained in:
		
							parent
							
								
									db73d04f0d
								
							
						
					
					
						commit
						8c5cfd88d9
					
				@ -1,65 +1,88 @@
 | 
				
			|||||||
const graph_density = 1000;
 | 
					import findLoudness, { SwapPoint } from "./find-loudness";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const graph_density = 8000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const threshold_at_point = 1;
 | 
					const threshold_at_point = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const inertia_s = 0.1;
 | 
					const inertia_s = 0.3;
 | 
				
			||||||
const inertia_samples = inertia_s * graph_density;
 | 
					const inertia_samples = inertia_s * graph_density;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let position = 0;
 | 
					const s = (n: number) => n / graph_density;
 | 
				
			||||||
let last_swap_position = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const s = (n: number) => Math.round(n / graph_density);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const minutes = (units: number) => Math.floor(s(units) / 60);
 | 
					const minutes = (units: number) => Math.floor(s(units) / 60);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const hours = (units: number) => Math.floor(units / graph_density / 60 / 60);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const formatTime = (units: number) =>
 | 
					const formatTime = (units: number) =>
 | 
				
			||||||
	`${minutes(units)}:${Math.floor(s(units) % 60)}`;
 | 
						`${hours(units)}:${minutes(units)}:${Math.floor(s(units) % 60)}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let keep_loud_until = 0;
 | 
					type Mode = { left: boolean; right: boolean };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let total_speaking = 0;
 | 
					async function run() {
 | 
				
			||||||
 | 
						const [left_breaks, right_breaks] = await Promise.all([
 | 
				
			||||||
const results: [string, number][] = [];
 | 
							findLoudness(
 | 
				
			||||||
 | 
								"/tmp/leftraw",
 | 
				
			||||||
process.stdin.on("readable", () => {
 | 
								threshold_at_point,
 | 
				
			||||||
	let chunk: Buffer | null;
 | 
								inertia_samples,
 | 
				
			||||||
	let was_loud_last_time = false;
 | 
								"left"
 | 
				
			||||||
	while ((chunk = process.stdin.read()) !== null) {
 | 
							),
 | 
				
			||||||
		for (let i = 0; i < chunk.byteLength; i++) {
 | 
							findLoudness(
 | 
				
			||||||
			position++;
 | 
								"/tmp/rightraw",
 | 
				
			||||||
			const byte = chunk[i];
 | 
								threshold_at_point,
 | 
				
			||||||
			const volume = Math.abs(byte - 128);
 | 
								inertia_samples,
 | 
				
			||||||
			const is_loud: boolean =
 | 
								"right"
 | 
				
			||||||
				volume > threshold_at_point || position < keep_loud_until;
 | 
							),
 | 
				
			||||||
			if (is_loud) {
 | 
					 | 
				
			||||||
				total_speaking++;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (is_loud != was_loud_last_time) {
 | 
					 | 
				
			||||||
				results.push([
 | 
					 | 
				
			||||||
					is_loud ? "silence" : "speaking",
 | 
					 | 
				
			||||||
					position - last_swap_position,
 | 
					 | 
				
			||||||
	]);
 | 
						]);
 | 
				
			||||||
				last_swap_position = position;
 | 
					
 | 
				
			||||||
				was_loud_last_time = is_loud;
 | 
						const merged = [...left_breaks, ...right_breaks].sort((a, b) =>
 | 
				
			||||||
 | 
							a.position_start < b.position_start
 | 
				
			||||||
 | 
								? -1
 | 
				
			||||||
 | 
								: a.position_start > b.position_start
 | 
				
			||||||
 | 
								? 1
 | 
				
			||||||
 | 
								: 0
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// console.log("left breaks:", left_breaks);
 | 
				
			||||||
 | 
						// console.log(`right_breaks`, right_breaks);
 | 
				
			||||||
 | 
						// console.log(`merged`, merged);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function new_mode(m: Mode, s: SwapPoint): Mode {
 | 
				
			||||||
 | 
							return { ...m, [s.label]: s.loud };
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
			if (volume > threshold_at_point) {
 | 
					
 | 
				
			||||||
				keep_loud_until = position + inertia_samples;
 | 
						function mode_to_string(mode: Mode) {
 | 
				
			||||||
 | 
							if (mode.left && mode.right) {
 | 
				
			||||||
 | 
								return "both";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (const side of ["left", "right"]) {
 | 
				
			||||||
 | 
								if (mode[side as keyof Mode]) {
 | 
				
			||||||
 | 
									return side;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							return "none";
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const mode_to_image = (mode: string) => {
 | 
						console.log("file", `${process.cwd()}/pics/none.png`);
 | 
				
			||||||
	return mode === "silence" ? "pics/cisza.png" : "pics/kuba.png";
 | 
						let last_point = 0;
 | 
				
			||||||
};
 | 
						let mode: Mode = { left: false, right: false };
 | 
				
			||||||
 | 
						let last_file;
 | 
				
			||||||
process.stdin.on("end", () => {
 | 
						let total = 0;
 | 
				
			||||||
	results.forEach(([mode, duration_units]) => {
 | 
						for (let i = 2; i < merged.length; i++) {
 | 
				
			||||||
		console.log("file", `'${mode_to_image(mode)}'`);
 | 
							const point = merged[i];
 | 
				
			||||||
		console.log("duration", (duration_units / graph_density).toFixed(4));
 | 
							mode = new_mode(mode, point);
 | 
				
			||||||
	});
 | 
							const file = `${process.cwd()}/pics/${mode_to_string(mode)}.png`;
 | 
				
			||||||
 | 
							const duration = (point.position_start - last_point) / graph_density;
 | 
				
			||||||
	console.log("file", `'${mode_to_image(results[results.length - 1][0])}'`);
 | 
							console.log(
 | 
				
			||||||
 | 
								"duration",
 | 
				
			||||||
	// console.log(formatTime(total_speaking), formatTime(position));
 | 
								(point.position_start - last_point) / graph_density
 | 
				
			||||||
});
 | 
							);
 | 
				
			||||||
 | 
							console.log("file", file);
 | 
				
			||||||
 | 
							last_point = point.position_start;
 | 
				
			||||||
 | 
							last_file = file;
 | 
				
			||||||
 | 
							total += duration * graph_density;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						console.log("duration", merged[merged.length - 1].duration / graph_density);
 | 
				
			||||||
 | 
						console.log("file", last_file);
 | 
				
			||||||
 | 
						console.error(total, formatTime(total));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					run();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										18
									
								
								generate.sh
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								generate.sh
									
									
									
									
									
								
							@ -11,25 +11,27 @@ input=/home/kuba/Downloads/podcast-01-after-effects.mp3  # tutaj dajemy ścieżk
 | 
				
			|||||||
aresample=8000   # to bez zmian
 | 
					aresample=8000   # to bez zmian
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo dzielimy mp3 na dwa osobne wav
 | 
					echo dzielimy mp3 na dwa osobne wav
 | 
				
			||||||
ffmpeg -i $input -map_channel 0.0.0 /tmp/left.wav -map_channel 0.0.1 /tmp/right.wav
 | 
					#ffmpeg -i $input -map_channel 0.0.0 /tmp/left.wav -map_channel 0.0.1 /tmp/right.wav
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo na dwóch wątkach generujemy surowe pliki
 | 
					echo na dwóch wątkach generujemy surowe pliki
 | 
				
			||||||
ffmpeg -i /tmp/left.wav -ac 1 -filter:a aresample=$aresample -map 0:a -c:a pcm_u8 -f data -  > /tmp/leftraw &
 | 
					#ffmpeg -i /tmp/left.wav -ac 1 -filter:a aresample=$aresample -map 0:a -c:a pcm_u8 -f data -  > /tmp/leftraw &
 | 
				
			||||||
ffmpeg -i /tmp/right.wav -ac 1 -filter:a aresample=$aresample -map 0:a -c:a pcm_u8 -f data -  > /tmp/rightraw &
 | 
					#ffmpeg -i /tmp/right.wav -ac 1 -filter:a aresample=$aresample -map 0:a -c:a pcm_u8 -f data -  > /tmp/rightraw &
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# czekamy aż obydwa wątki się zakończą
 | 
					# czekamy aż obydwa wątki się zakończą
 | 
				
			||||||
wait;
 | 
					#wait;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "generating the demuxers...";
 | 
					echo "generating the demuxers...";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# generuje ścieżki do złożenia przez ffmpega:
 | 
					# generuje ścieżki do złożenia przez ffmpega:
 | 
				
			||||||
ts-node generate-demuxer.ts  > /tmp/demuxer.txt
 | 
					ts-node generate-demuxer.ts  > out/demuxer.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mkdir -f out
 | 
					mkdir -p out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# używa demuxer.txt żeby skleić końcowe video z dźwiękiem:
 | 
					# używa demuxer.txt żeby skleić końcowe video z dźwiękiem:
 | 
				
			||||||
echo generowanie całości
 | 
					echo generowanie całości
 | 
				
			||||||
ffmpeg -y -f concat -i /tmp/demuxer.txt -r 30 -tune stillimage -vsync vfr -pix_fmt yuv420p out/video.mp4
 | 
					ffmpeg -y -f concat -safe 0 -i out/demuxer.txt -r 30 -tune stillimage -vsync vfr -pix_fmt yuv420p out/video.mp4
 | 
				
			||||||
 | 
					#                   ^ daję safe 0 aby przyjmowało bezwzględne ścieżki
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo łączenie video z dźwiękiem:
 | 
					echo łączenie video z dźwiękiem:
 | 
				
			||||||
ffmpeg  -i video.mp4 -i $input -ac 1 -tune stillimage out/video-and-audio.mp4
 | 
					ffmpeg  -i out/video.mp4 -i $input -ac 1 -tune stillimage out/video-and-audio.mp4
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user