在heroku app加上ffmpeg轉檔
因為最近想要使line bot可以接受影音資料並儲存起來供瀏覽器瀏覽,會需要有轉檔的機制,因為之前已經做過node.js的line bot就繼續延伸下。
1. 你得先有一個line bot
因為本文是以line bot做範例,你可以參考我之前的文章建立Line bot;實際上,你有其他app也是ok的。
2. 加入含有ffmpeg的buildpack
$ heroku buildpacks:add --index 1 https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git
加入後可用指令確認一下專案使用的buildpack狀態
$ heroku buildpacks
然後就再deploy一版上heroku它就可以用ffmpeg了。要確認線上是否可用ffmpeg,你可以bash登入後打ffmpeg指令
$ heroku run bash$ ffmpeg
特別強調: 如果你有自己build的ffmpeg檔案也可以用這個buildpack。之後對影片的部份我再弄一篇出來。
3. 為node.js安裝fluent-ffmpeg
$ yarn add fluent-ffmpeg
$ yarn add -D @types/fluent-ffmpeg
4. 建構你的轉檔程式
這裡以line錄音檔.m4a轉成wav為例
const ffmpeg = require('fluent-ffmpeg');
function m4a2wav(inpath, outpath) {
console.log('m4a2wav', inpath, outpath);
return new Promise((resolve, reject) => {
ffmpeg(inpath).inputFormat('m4a')
.on('error', (err, stdout, stderr) => {
console.error('Cannot process: ', err.message, 'err', stderr, 'std', stdout);
reject(new Error('Cannot process: ' + err.message))
})
.on('end', resolve)
.toFormat('wav').withAudioFrequency(16000).audioChannels(1)
.save(outpath);
});
}
module.exports = { m4a2wav };
5. 將轉檔加入你的app
以我的bot為例,會先將m4a存檔後
function storeAudioFileByMsgId(id, filePath) {
return new Promise((resolve, reject) => {
if (!id) return reject(new Error('invalid id'));
client.getMessageContent(id).then((stream) => {
stream.on('error', reject)
.on('end', () => resolve())
.pipe(fs.createWriteStream(filePath));
}).catch(reject);
});
}
再執行轉檔
async function onMessage(event) {
if ('audio' !== event.message.type) return;
console.log('onAudioMessage', event.message);
const { id } = event.message;
const m4aPath = path.join(STORAGE_DIR_NAME, id + '.m4a');
await storeAudioFileByMsgId(id, m4aPath);
await m4a2wav(m4aPath, path.join(STORAGE_DIR_NAME, id + '.wav'));
return client.replyMessage(event.replyToken, { type: 'text', text: 'done' });
}
6. 發布到heoku
就像往常一樣發布到heroku
留言