This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
虽然默认行为是完整加载声音数据,但在使用前分块加载数据可能也是有益的。这通常被称为”流传输”。
声音流传输的一个好处是需要更少的运行时内存,另一个好处是如果您从例如 http url 流式传输内容,您可以随时更新内容,并避免初始下载。
有一个展示此设置的示例项目:https://github.com/defold/example-sound-streaming
使用声音流传输的最简单方法是在 game.project 中启用 sound.stream_enabled
设置。启用此选项后,引擎将开始流式传输声音。
注意:如果您同时加载了许多声音文件,可能需要增加 sound.stream_cache_size
值(见下文)。
您也可以创建一个新的声音数据资源,并将其设置为声音组件。
您可以通过以下方式执行此操作:
resource.create_sound_data()
创建一个新的声音数据资源go.set()
将新的声音数据资源设置为声音组件以下是示例项目中的摘录,使用 http.request()
获取初始声音文件。
您从中加载内容的 Web 服务器必须支持 HTTP 范围请求。
local function play_sound(self, hash)
go.set(self.component, "sound", hash) -- 覆盖组件上的资源数据
sound.play(self.component) -- 开始播放声音
end
local function parse_range(s)
local _, _, rstart, rend, size = string.find(s, "(%d+)-(%d+)/(%d+)") -- "bytes 0-16383/103277"
return rstart, rend, size
end
-- http 响应的回调函数
local function http_result(self, _id, response, extra)
if response.status == 200 or response.status == 206 then
-- 成功的请求
local relative_path = self.filename
local range = response.headers['content-range'] -- content-range = "bytes 0-16383/103277"
local rstart, rend, filesize = parse_range(range)
-- 创建 Defold 资源
-- "partial" 将启用流传输模式
print("Creating resource", relative_path)
local hash = resource.create_sound_data(relative_path, { data = response.response, filesize = filesize, partial = true })
-- 发送 "play_sound" 到组件
play_sound(self, hash)
end
end
local function load_web_sound(base_url, relative_path)
local url = base_url .. "/" .. relative_path
local headers = {}
headers['Range'] = string.format("bytes=%d-%d", 0, 16384-1)
http.request(url, "GET", http_result, headers, nil, { ignore_cache = true })
end
您可以使用其他方式加载声音文件的初始块。重要的是要记住,其余的块是从资源系统及其资源提供者加载的。在此示例中,我们通过调用使用 liveupdate.add_mount() 添加一个新的 (http) 文件提供者,通过添加实时更新挂载点。
您可以在 https://github.com/defold/example-sound-streaming 中找到一个工作示例。
-- 参见上面示例中的 http_result()
local function load_web_sound(base_url, relative_path)
local url = base_url .. "/" .. relative_path
local headers = {}
-- 请求文件的初始部分
headers['Range'] = string.format("bytes=%d-%d", 0, 16384-1)
http.request(url, "GET", http_result, headers, nil, { ignore_cache = true })
end
function init(self)
self.base_url = "http://my.server.com"
self.filename = "/path/to/sound.ogg"
liveupdate.add_mount("webmount", self.base_url, 100, function ()
-- 一旦挂载点准备就绪,我们就可以开始请求下载第一个块
load_web_sound(self.base_url, self.filename)
end)
end
function final(self)
liveupdate.remove_mount("webmount")
end
运行时声音消耗的内存量由 game.project 中的 sound.stream_cache_size
设置 控制。在此限制下,加载的声音数据永远不会超过此限制。
每个声音文件的初始块不能被驱逐,只要资源被加载,它们就会占用缓存。初始块的大小由 game.project 中的 sound.stream_preload_size
设置 控制。
您还可以通过更改 game.project 中的 sound.stream_chunk_size
设置 来控制每个声音块的大小。如果您同时加载了许多声音文件,这可能有助于进一步降低声音缓存大小。小于声音块大小的声音文件不会被流式传输,如果新块不适合放入缓存中,最旧的块将被驱逐。
声音块缓存的总大小应大于加载的声音文件数量乘以流块大小。否则,您可能会冒着每帧驱逐新块的风险,声音将无法正常播放。
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB