一行有趣的代码

作者:David Bushell

原文:https://dbushell.com/2024/02/27/a-fun-line-of-code/

代码可以既有趣又富有创意。有时候我必须自己控制,否则我很容易写出为了创意而创作的代码,这样的代码并不总是最易读的。然而,有时候有趣的解决方案确实是最好的。

我正在更新我的 Deno Audio Duration 包,以在 JSR 上发布它,这让我想起了一段有趣的代码。这个脚本在原生 Deno 中获取MP3和M4A音频文件的毫秒级持续时间,而无需任何依赖。虽然存在用于解析音频文件的现有JavaScript库,但它们占用空间很大。我只需要持续时间。

获取持续时间的一种简便方法是通过 Deno.Command 调用 ffprobeexiftool,但这取决于第三方二进制文件。这样会迅速使Docker镜像变得臃肿。

MP3文件没有用于持续时间的元数据。必须在解析帧、采样率、比特率等之后进行估算。我的MP3解决方案改编了其他开源项目的代码,以使用Deno API并添加了类型。

M4A音频文件、M4B有声读物和MP4视频使用相同的容器规范,其中确实包含了持续时间的元数据。我的M4A解决方案搜索“电影头部原子”中存储的秘密。

这些数据通常位于文件的开头,这是一个允许快速检查的逻辑位置。然而,并非必须如此。通过对我的有声读物库进行测试,我发现元数据似乎可以位于文件的任何位置,通常朝文件末尾。我甚至在一本冗长的有声读物中找到了它直接在中间。

这就引出了我最喜欢的代码之一:

export const m4aDuration = async (path: string): Promise<number> => {
  const controller = new AbortController();
  const duration = await Promise.race([
    search(path, controller.signal),
    search(path, controller.signal, true)
  ]);
  controller.abort();
  return duration;
};

具体来说是 Promise.race

Promise 或许是我最喜欢的JavaScript API之一。结合 async await 编写异步代码真的很有趣。

上面的代码设置了两个异步调用,以搜索MP4头部。第一个从文件的开头开始搜索,第二个从文件的末尾开始搜索。

race 在其中之一返回持续时间时解析。

默认情况下,比赛后另一个promise实际上会在背景中继续运行。如果不加以处理,它要么解析到虚无中,要么可能并不那么安静地拒绝。为了停止它,我使用了 AbortController 来发出放弃的信号。内部循环通过 if (signal.aborted) break; 中断并关闭文件句柄。

这并不是世界上最快的代码。但对于一个本地不到100行的实现来说,效果非常好。

我觉得比赛代码的想法很有趣!而且这是一个合理的用例!请不要在评论中提及我,破坏这个梦想。可以竞争超过两个promise。你在野外见过吗?

愿你编码愉快!

2024-03-04

访问量 71

扫码关注公众号“前端微志”

第一时间获取新周刊

预览图片