Vorbis 与 Opus 编码
摘自 Wikipedia:
Vorbis
Vorbis 是一種有損音訊壓縮格式,由 Xiph. Org 基金會所領導並開放原始碼的一個免費的開源軟件項目。該項目為有損音頻壓縮產生音頻編碼格式和軟件參考編碼器╱解碼器(編解碼器)。Vorbis 通常以 Ogg 作為容器格式,所以常合稱為 Ogg Vorbis。
Vorbis 是 1993 年由克里斯·蒙哥馬利開始的音頻壓縮開發的延續。1998 年 9 月,夫朗和斐協會宣布計劃收取 MP3 音頻格式的專利許可費用,该事件触发了 Vorbis 的密集开发 。Vorbis 項目是 Xiphophorus 公司的 Ogg 項目(也稱為 OggSquish 多媒體項目)的一部分。克里斯·蒙哥馬利開始了這個項目的工作,並得到越來越多的其他開發者的幫助。他們繼續改進源代碼,直到 Vorbis 文件格式在 2000 年 5 月被凍結為 1.0。原來授權為 LGPL,2001 年,Vorbis 許可證被更改為 BSD 許可證,以鼓勵採納,理查德·斯托曼參考軟件的穩定版本(1.0)於 2002 年 7 月 19 日發布 。
Xiph. Org 基金會維護一個參考實現編解碼器 libvorbis。還有一些微調的分支,最引人注目的是 aoTuV,提供更好的音頻質量,特別是在低比特率。這些改進會定期地合併回參考代碼庫。
目前 Xiph. Org 基金會建議使用延遲更低、音質更好的 Opus 編碼來取代 Vorbis。
Opus
Opus 是一個有損聲音編碼的格式,由 Xiph. Org 基金會開發,之後由網際網路工程任務組進行標準化,目標是希望用單一格式包含聲音和語音,取代 Speex 和 Vorbis,且適用於網路上低延遲的即時聲音傳輸,標準格式定義於 RFC 6716 文件。Opus 格式是一個開放格式,使用上沒有任何專利或限制。
Opus 整合了兩種聲音編碼的技術:以語音編碼為導向的 SILK 和低延遲的 CELT。Opus 可以无缝调节高低比特率。在编码器内部它在较低比特率时使用线性预测编码在高比特率时候使用变换编码(在高低比特率交界处也使用两者结合的编码方式)。Opus 具有非常低的演算法延遲(預設為 22.5 ms),非常適合用於低延遲語音通話的編碼,像是網路上的即時聲音串流、即時同步聲音旁白等等,此外 Opus 也可以透過降低編碼位元率,達成更低的演算法延遲,最低可以到 5 ms。在多個聽覺盲測中,Opus 都比 MP3、AAC、HE-AAC 等常見格式,有更低的延遲和更好的聲音壓縮率。
Vorbis 与 Opus 的浏览器支持情况
音频编码 Opus 与 Vorbis 中,Safari 完全不支持 Vorbis 编码,支持 CAF 封装的 Opus 编码文件。
但 CAF(Core Audio Format) 是苹果的专有格式,其他浏览器并不支持。因此,想要在网页中使用 Opus 编码,需要同时准备两份文件,一份 CAF 封装,一份 Ogg 封装(.ogg 或者 .opus)。
转换 Opus 格式
用 FFmpeg 可以很方便的转换 Opus 到 CAF:
FOR %%a IN (.\*.opus) DO ("ffmpeg" -i "%%a" -c:a copy "%%a.caf")
保存成批处理可以将当前文件夹下的所有 Opus 文件生成一份 caf 封装的副本。
使用 Nginx 分流提供不同格式文件
这样做的好处是不需要修改前端代码,代码中统一使用 Opus 或者 Ogg 格式,但 Nginx 会根据不同的浏览器返回不同文件。
利用 Nginx 的内置变量和 URL 重写功能,对请求的 UserAgent 进行判断,符合条件的请求会被重写。
因为 Nginx 不支持在一个条件中判断多个表达式和 if 语句的嵌套,只能利用自定义变量实现多条件判断。
对于 Safari 浏览器,如果接收的文件不是以 .caf 结尾,则必须正确指定 Content-Type 才能播放。
另外,对于这种改写方法,由于请求地址是一样的,必须要在 Cache-Control 中指定为 private,否则 CDN 可能缓存错误的文件,导致浏览器无法播放。
location /media/ {
root /srv/nginx/hexo_media/;
add_header Cache-Control "private, max-age=31536000";
types {
audio/x-caf caf;
}
set $flag "";
if ( $http_user_agent !~* Chrome ){
set $flag "${flag}NotChrome";
}
if ( $http_user_agent ~* Safari ){
set $flag "${flag}IsSafari";
}
if ( $uri ~* \.opus$ ){
set $flag "${flag}Opus";
}
if ( $uri ~* \.ogg$ ){
set $flag "${flag}Ogg";
}
if ( $flag = "NotChromeIsSafariOpus" ){
rewrite (.*)\.opus$ $1.opus.caf;
}
if ( $flag = "NotChromeIsSafariOgg" ){
rewrite (.*)\.ogg$ $1.opus.caf;
}
}