在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



留言