all repos — telegram-bot-api @ 3a401563b5a6428f3d6a4f76d6d2d8e109ff52c1

Golang bindings for the Telegram Bot API

tgutils/audio.go (view raw)

 1// Package tgutils provides extra functions to make certain tasks easier.
 2package tgutils
 3
 4import (
 5	"github.com/syfaro/telegram-bot-api"
 6	"log"
 7	"os"
 8	"os/exec"
 9	"path/filepath"
10	"strconv"
11	"sync"
12	"time"
13)
14
15var rand uint32
16var randmu sync.Mutex
17
18func reseed() uint32 {
19	return uint32(time.Now().UnixNano() + int64(os.Getpid()))
20}
21
22func nextSuffix() string {
23	randmu.Lock()
24	r := rand
25	if r == 0 {
26		r = reseed()
27	}
28	r = r*1664525 + 1013904223 // constants from Numerical Recipes
29	rand = r
30	randmu.Unlock()
31	return strconv.Itoa(int(1e9 + r%1e9))[1:]
32}
33
34// this function ripped from ioutils.TempFile, except with a suffix, instead of prefix.
35func tempFileWithSuffix(dir, suffix string) (f *os.File, err error) {
36	if dir == "" {
37		dir = os.TempDir()
38	}
39
40	nconflict := 0
41	for i := 0; i < 10000; i++ {
42		name := filepath.Join(dir, nextSuffix()+suffix)
43		f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
44		if os.IsExist(err) {
45			if nconflict++; nconflict > 10 {
46				randmu.Lock()
47				rand = reseed()
48				randmu.Unlock()
49			}
50			continue
51		}
52		break
53	}
54	return
55}
56
57// EncodeAudio takes a file and attempts to convert it to a .ogg for Telegram.
58// It then returns an AudioConfig.
59//
60// This function requires ffmpeg and opusenc to be installed on the system!
61func EncodeAudio(audio *tgbotapi.AudioConfig) error {
62	f, err := tempFileWithSuffix(os.TempDir(), "_tgutils.ogg")
63	if err != nil {
64		return err
65	}
66	defer f.Close()
67
68	log.Println(f.Name())
69
70	ffmpegArgs := []string{
71		"-i",
72		audio.FilePath,
73		"-f",
74		"wav",
75		"-",
76	}
77
78	opusArgs := []string{
79		"--bitrate",
80		"256",
81		"-",
82		f.Name(),
83	}
84
85	c1 := exec.Command("ffmpeg", ffmpegArgs...)
86	c2 := exec.Command("opusenc", opusArgs...)
87
88	c2.Stdin, _ = c1.StdoutPipe()
89	c2.Stdout = os.Stdout
90	c2.Start()
91	c1.Run()
92	c2.Wait()
93
94	return nil
95}