Skip to content

Instantly share code, notes, and snippets.

@TarasMazepa
Created July 19, 2023 16:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TarasMazepa/e30db82d21e6d983d7995782b637f580 to your computer and use it in GitHub Desktop.
Save TarasMazepa/e30db82d21e6d983d7995782b637f580 to your computer and use it in GitHub Desktop.
google/zx showcase
#!/usr/bin/env zx
cd(`/Users/tarasmazepa`);
await $`rm temp.mp4 temp.mkv audio.mp3`.nothrow();
const script =
argv._[0] +
" Let me know in the comments what other life situation you want me to talk next. Subscribe, follow, and give a like to hear more stories like this.";
const ssml = `<speak>${script
.replace(/([.?!])\s*(?=[A-Z])/g, "$1|")
.split("|")
.filter((s) => s.length > 0)
.flatMap((text, i) => [
`<mark name="${i}~${text}"/>`,
text,
`<mark name="${i}"/>`,
])
.join("")}</speak>`;
const response = await $`curl -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-H "X-Goog-User-Project:lyflair-production" \
-d ${JSON.stringify({
input: {
ssml,
},
voice: {
languageCode: "en-US",
name: "en-US-Wavenet-F",
},
audioConfig: {
audioEncoding: "MP3",
pitch: 2.35,
speakingRate: 1.1,
},
enableTimePointing: ["SSML_MARK"],
})} "https://texttospeech.googleapis.com/v1beta1/text:synthesize"`.then((r) =>
JSON.parse(r.stdout)
);
if (!response?.timepoints?.length) exit(1);
console.log(response.timepoints);
let subtitles = "";
const secondsToTimestamp = (seconds) =>
new Date(seconds * 1000).toISOString().substr(11, 12).replace(".", ",");
for (let i = 0; i < response.timepoints.length - 1; i++) {
subtitles += `${i}
${secondsToTimestamp(
response.timepoints[i].timeSeconds
)} --> ${secondsToTimestamp(response.timepoints[i + 1].timeSeconds)}
${response.timepoints[i].markName.split("~")[1].trim()}
`;
}
await $`echo ${subtitles} > srt.srt`;
await $`echo ${response.audioContent}`.pipe($`base64 -d > audio.mp3`);
const videos = await $`find pexels -type f -name '*mp4'`
.pipe($`sort -R | head -n $((($(mp3info -p "%S" audio.mp3)-1)/3+1))`)
.then((r) => r.stdout.split("\n").filter((s) => s.length > 0));
const numbers = videos.map((_, i) => i + 1);
await $`ffmpeg -i audio.mp3 ${videos.flatMap((s) => [
"-i",
s,
])} -filter_complex ${`${numbers
.map((i) => `[${i}:v:0]scale=1080:1920,trim=duration=3[v${i}]`)
.join(";")}, ${numbers.map((i) => `[v${i}]`).join(" ")} concat=n=${
videos.length
}:v=1 [v]`} -map "[v]" -map 0:a temp.mkv -y`;
const folder = "imgonnahelp-promo-videos";
await $`mkdir ${folder}`.nothrow();
const outputFileName = `${folder}/${new Date()
.toISOString()
.replace(/\W/g, "_")}.mp4`;
await $`ffmpeg -i temp.mkv -lavfi "subtitles=srt.srt:force_style='Alignment=10'" ${outputFileName} -y`;
await $`open ${outputFileName} -a mkplayer`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment