feat: upload audio, get a private Swedish transcript, discuss it (#33, ADR-033) #39
@@ -27,8 +27,10 @@ func (f *FFmpeg) ToWAV(ctx context.Context, src, dst string) error {
|
|||||||
if bin == "" {
|
if bin == "" {
|
||||||
bin = "ffmpeg"
|
bin = "ffmpeg"
|
||||||
}
|
}
|
||||||
cmd := exec.CommandContext(ctx, bin,
|
// Input restrictions go BEFORE -i: placed after it they would apply to the output.
|
||||||
"-y", "-v", "error", "-i", src, "-vn", "-ac", "1", "-ar", "16000", "-c:a", "pcm_s16le", "-f", "wav", dst)
|
args := append([]string{"-y", "-v", "error"}, inputRestrictions...)
|
||||||
|
args = append(args, "-i", src, "-vn", "-ac", "1", "-ar", "16000", "-c:a", "pcm_s16le", "-f", "wav", dst)
|
||||||
|
cmd := exec.CommandContext(ctx, bin, args...)
|
||||||
cmd.WaitDelay = killGrace
|
cmd.WaitDelay = killGrace
|
||||||
if out, err := cmd.CombinedOutput(); err != nil {
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
if ctxErr := ctx.Err(); ctxErr != nil {
|
if ctxErr := ctx.Err(); ctxErr != nil {
|
||||||
|
|||||||
@@ -21,6 +21,19 @@ type FFprobe struct {
|
|||||||
Bin string
|
Bin string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllowedDemuxers are the input formats an upload may be. The input is
|
||||||
|
// attacker-supplied, and a file's CONTENT can tell ffmpeg to open other files or
|
||||||
|
// URLs (HLS and concat playlists, image2 sequences, network demuxers). Recent
|
||||||
|
// ffmpeg refuses the ones tried (7.0.2: HLS without a .m3u8 name is not sniffed,
|
||||||
|
// concat rejects unsafe paths), but that is version luck; this list is not. It
|
||||||
|
// holds the containers real recordings use and none of the playlist or network
|
||||||
|
// formats. "mov" covers .mp4/.m4a/.3gp; "matroska" covers .webm.
|
||||||
|
const AllowedDemuxers = "wav,mov,mp4,m4a,3gp,mp3,ogg,matroska,webm,flac,aac,opus,aiff,amr,asf"
|
||||||
|
|
||||||
|
// inputRestrictions are ffmpeg/ffprobe INPUT options and must precede the input.
|
||||||
|
// Local files and pipes only: no network, no other protocols.
|
||||||
|
var inputRestrictions = []string{"-protocol_whitelist", "file,pipe", "-format_whitelist", AllowedDemuxers}
|
||||||
|
|
||||||
// killGrace bounds how long Probe waits for a cancelled ffprobe's pipes to close.
|
// killGrace bounds how long Probe waits for a cancelled ffprobe's pipes to close.
|
||||||
const killGrace = 2 * time.Second
|
const killGrace = 2 * time.Second
|
||||||
|
|
||||||
@@ -34,8 +47,9 @@ func (f *FFprobe) Probe(ctx context.Context, path string) (uploads.Probe, error)
|
|||||||
if bin == "" {
|
if bin == "" {
|
||||||
bin = "ffprobe"
|
bin = "ffprobe"
|
||||||
}
|
}
|
||||||
cmd := exec.CommandContext(ctx, bin,
|
args := append([]string{"-v", "error"}, inputRestrictions...)
|
||||||
"-v", "error", "-print_format", "json", "-show_format", "-show_streams", path)
|
args = append(args, "-print_format", "json", "-show_format", "-show_streams", path)
|
||||||
|
cmd := exec.CommandContext(ctx, bin, args...)
|
||||||
cmd.WaitDelay = killGrace
|
cmd.WaitDelay = killGrace
|
||||||
out, err := cmd.Output()
|
out, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user