Skip to content

Instantly share code, notes, and snippets.

@7shi
Last active May 13, 2020 21:16
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 7shi/a7ce15c0a48659b4cf1cd212b36bb64d to your computer and use it in GitHub Desktop.
Save 7shi/a7ce15c0a48659b4cf1cd212b36bb64d to your computer and use it in GitHub Desktop.
[F#][make] 読み上げ動画の生成
TARGET = foo
MKWAV = ~/bin/wintts -o $$wav `python ssml_lfn.py -l pl-PL -f $$txt`
SILENT = ffmpeg -t 00:00:02 -f s16le -i /dev/zero -acodec pcm_s16le -ar 22050 -ac 1 $$wav
MKAVI = ffmpeg -loop 1 -i $$png -i $$wav -vcodec mpeg4 -acodec pcm_s16le -shortest $$avi
all: $(TARGET).mp4
clean:
rm -f $(TARGET).mp4 $(TARGET).lst $(TARGET)-*.avi $(TARGET)-*.wav $(TARGET)-*.png $(TARGET)-*.txt
$(TARGET).mp4: $(TARGET).lst
ffmpeg -f concat -i $< -vcodec libx264 -acodec aac -pix_fmt yuv420p $@
$(TARGET).lst: png wav avi
for avi in $(TARGET)-*.avi; do echo file $$avi; done > $@
define chgext
`echo $1 | sed 's/\.[^.]*$$/.$2/'`
endef
define exists
if [ ! -f $1 ]; then echo $1; $2; fi
endef
define forpng
for png in $(TARGET)-*.png; do avi=$(call chgext,$$png,avi); wav=$(call chgext,$$png,wav); txt=$(call chgext,$$png,txt); $1; done
endef
avi:
$(call forpng,$(call exists,$$avi,$(MKAVI)))
wav:
$(call forpng,$(call exists,$$wav,if [ -f $$txt ]; then $(MKWAV); else $(SILENT); fi))
png:
$(call exists,$(TARGET)-00.png,mkpngtxt $(TARGET).txt)
#r "System"
#r "System.Drawing"
#r "System.Windows.Forms"
open System
open System.Drawing
open System.IO
open System.Windows.Forms
let args = System.Environment.GetCommandLineArgs()
if args.Length <= 1 then
printfn "usage: %s file" args.[0]
exit 1
let font = new Font("Arial", 18.f, FontStyle.Regular)
let bgcols = [| Color.White; Color.FromArgb(0xb0, 0xd0, 0xff) |]
let w, margin = 640, 6
let h = w / 4 * 3
let bmp = new Bitmap(w, h)
let g = Graphics.FromImage bmp
let lines = File.ReadAllLines args.[1] |> Array.map (fun s -> s.Trim())
let fname = Path.GetFileNameWithoutExtension args.[1]
let flags = TextFormatFlags.NoPadding ||| TextFormatFlags.WordBreak
let proposedSize = Size(w, Int32.MaxValue)
let measure g line =
TextRenderer.MeasureText(g, line, font, proposedSize, flags)
let sizes = lines |> Array.map (measure g)
let maxw = sizes |> Seq.map (fun size -> size.Width) |> Seq.max
let allh = sizes |> Seq.map (fun size -> size.Height + margin * 2) |> Seq.sum
let draw sel =
g.Clear(Color.White)
let mutable p = Point((w - maxw) / 2, (h - 32 - allh) / 2)
lines |> Seq.iteri (fun i line ->
let r = Rectangle(p, measure g line)
let bg = bgcols.[if i + 1 = sel then 1 else 0]
TextRenderer.DrawText(g, line, font, r, Color.Black, bg, flags)
p.Y <- p.Y + r.Height + margin * 2)
let maxlen = lines.Length.ToString().Length
let format (i:int) =
let s = String('0', maxlen) + i.ToString()
s.[s.Length - maxlen ..]
let save sel =
draw sel
let fname = fname + "-" + format sel
bmp.Save(fname + ".png", Imaging.ImageFormat.Png)
if 1 <= sel && sel <= lines.Length then
File.WriteAllText(fname + ".txt", lines.[sel - 1])
#if !DEDBUG
for i = 0 to lines.Length + 1 do
save i
#else
let mutable sel = 0
let f = new Form(ClientSize = Size(w, h))
f.Paint.Add <| fun e ->
if sel <= lines.Length + 1 then save sel
e.Graphics.DrawImage(bmp, 0, 0)
if sel <= lines.Length + 1 then
sel <- sel + 1
f.Invalidate()
Application.Run f
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment