如何将Python的BytesIO函数翻译为Node.js/TypeScript?

问题描述 投票:0回答:1

我目前正在使用 Svelte-Kit 和 Node.js 适配器将我的 Python 后端与 Svelte 前端合并。我有一个媒体文件作为缓冲区,我试图找出如何将所有内容保留在内存中,类似于我在 Python 中使用 BytesIO 实现的方法。

这是我尝试将其转换为 TypeScript / Node.js 的 Python 函数:

def get_duration(input: BytesIO):
    command = "ffmpeg -i -".split(" ")
    output = subprocess.run(
        command,
        input=input.read(),
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )
    duration = None
    lines = output.stderr.decode().split("\n")
    print(lines)
    for line in lines:
        if "Duration:" in line:
            match = re.search(r"Duration: (\d+):(\d+):(\d+.\d+)", line)
            if match:
                hours = int(match.group(1))
                minutes = int(match.group(2))
                seconds = float(match.group(3))
                duration = hours * 3600 + minutes * 60 + seconds
            break
    input.seek(0)
    print(duration)
    return duration

这个函数在 Python 中运行良好,但我不确定如何将其转换为 Node.js,同时将所有内容保留在内存中。我需要将字节通过管道传输到标准输入,并将标准输出和标准错误通过管道传输到内存中的对象。

我怀疑这可能涉及 Node.js 的“fs”库,但我不确定是否使用流或缓冲区。

注意:我没有在持续时间内使用 ffprobe,因为它在持续时间内不断产生零(可能是由于我这边的错误)。

我尝试过使用 GPT-4,搜索 Node.js 文档,并浏览 StackOverflow 以获取有关内存管道传输的答案。然而,我对 Node.js 不像对 Python 那样熟悉,而 Python 对对象的更高层次的抽象让我可以避免学习流、缓冲区、字节等。

GPT-4 表明不可能使用 Node.js 在 Python 函数中完成我所做的事情,但我发现这很难相信。

我还研究了 createWriteStream(),但第一个参数似乎需要一个 FileLike 对象,并且我认为 Buffer 不适合该上下文。

python node.js typescript stream buffer
1个回答
0
投票

我已经通过可读和可写弄清楚了。由于标准输入上的错误,我遇到了测试提前退出的问题。事实证明,这是由 Vitest 使用多个工作人员运行测试引起的。我还切换回了 FFProbe,它似乎没有出现与 Python 相同的问题。

以下是返回视频或音频文件的持续时间(以秒为单位),同时将所有内容保留在内存中的样子:

export async function getDuration(input: Buffer): Promise<number | undefined> {
    if (!Buffer.isBuffer(input)) {
        throw new Error('Input must be a buffer.')
    }

    if (input.length === 0) {
        throw new Error('Input must have a length.')
    }

    return new Promise((resolve, reject) => {
        const output = spawn(
            'ffprobe',
            ['-i', '-', '-show_entries', 'format=duration', '-print_format', 'json'],
            {
                stdio: ['pipe', 'pipe', 'pipe']
            }
        )

        let jsonOutput = ''

        output.stdout.on('data', (data) => {
            jsonOutput += data
        })

        output.on('exit', (code, signal) => {
            console.log(`ffprobe exited with code ${code} and signal ${signal}`)
            if (code !== 0) {
                reject(new Error(`FFprobe exited with code ${code}`))
                return
            }

            try {
                const { format } = JSON.parse(jsonOutput)
                resolve(Number(format.duration))
            } catch (err) {
                reject(err)
            }
        })

        // Create a Readable stream from the input buffer
        const stream = new Readable()
        stream.push(input)
        stream.push(null) // indicates end-of-file

        // Pipe the stream to the stdin of the ffprobe process
        stream.pipe(output.stdin)

        // Handle EPIPE error
        output.stdin.on('error', (error) => {
            if (error.code !== 'EPIPE') {
                reject(error)
            }
        })
    })
}

绝对比 Python 更冗长......

我想转码的方式是相同的,只是将输出管道改为可写。

© www.soinside.com 2019 - 2024. All rights reserved.