1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- import {spawn} from 'node:child_process'
- import {promisifyProcess} from './general-util.js'
- // Some probers are sorta inconsistent; this function lets them try again if
- // they fail the first time.
- const tryAgain = function(times, func) {
- return async function(...args) {
- let n = 0
- let ret
- while (!ret && n < times) {
- try {
- ret = await func(...args)
- } catch (error) {
- if (n + 1 === times) {
- throw error
- }
- }
- n++
- }
- return ret
- }
- }
- const metadataReaders = {}
- metadataReaders.ffprobe =
- tryAgain(6, async filePath => {
- const ffprobe = spawn('ffprobe', [
- '-print_format', 'json',
- '-show_entries', 'stream=codec_name:format',
- '-select_streams', 'a:0',
- '-v', 'quiet',
- filePath
- ])
- let probeDataString = ''
- ffprobe.stdout.on('data', data => {
- probeDataString += data
- })
- try {
- await promisifyProcess(ffprobe, false)
- } catch (error) {
- return null
- }
- let data
- try {
- data = JSON.parse(probeDataString)
- } catch (error) {
- return null
- }
- if (typeof data !== 'object' || typeof data.format !== 'object') {
- return null
- }
- return {
- duration: parseFloat(data.format.duration),
- fileSize: parseInt(data.format.size),
- bitrate: parseInt(data.format.bit_rate)
- }
- })
- export default metadataReaders
- export function getMetadataReaderFor(_arg) {
- // Only the one metadata reader implemented, so far!
- return metadataReaders.ffprobe
- }
|