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
Aunque el comportamiento por defecto es cargar los datos de sonido completos, también puede ser beneficioso cargar los datos en fragmentos antes de usarlos. Esto suele llamarse “streaming”.
Una ventaja del streaming de sonido es que requiere menos memoria en tiempo de ejecución. Otra es que, si haces streaming de contenido desde, por ejemplo, una URL HTTP, puedes actualizar el contenido en cualquier momento y también evitar la descarga inicial.
Hay un proyecto de ejemplo que muestra esta configuración: https://github.com/defold/example-sound-streaming
La forma más simple de usar streaming de sonido es habilitar la configuración sound.stream_enabled en game.project. Cuando esta opción está habilitada, el motor empezará a hacer streaming de los sonidos.
Nota: Si tienes muchos archivos de sonido cargados al mismo tiempo, es posible que necesites aumentar el valor de sound.stream_cache_size (consulta más abajo).
También puedes crear un nuevo recurso de datos de sonido y asignarlo a un componente de sonido.
Para hacerlo:
resource.create_sound_data().go.set()Aquí hay un extracto del proyecto de ejemplo, que usa http.request() para obtener la parte inicial del archivo de sonido.
El streaming real requiere que el servidor web respete las solicitudes HTTP de rango y devuelva el estado 206. Si el servidor ignora el encabezado Range y devuelve el estado 200, el ejemplo siguiente crea en su lugar un recurso normal sin streaming a partir de la respuesta completa.
local function play_sound(self, hash)
go.set(self.component, "sound", hash) -- sobrescribe los datos del recurso en el componente
sound.play(self.component) -- empieza a reproducir el sonido
end
local function parse_content_range(value)
if not value then
return nil
end
local rstart, rend, filesize = value:match("^bytes%s+(%d+)%-(%d+)/(%d+)$")
return tonumber(rstart), tonumber(rend), tonumber(filesize)
end
-- Callback para la respuesta HTTP.
local function http_result(self, _id, response)
if response.status ~= 200 and response.status ~= 206 then
return
end
local options = {
data = response.response,
}
if response.status == 206 then
local rstart, _, filesize = parse_content_range(response.headers["content-range"])
if rstart ~= 0 or not filesize then
print("Invalid Content-Range response")
return
end
-- Un recurso parcial habilita el streaming. filesize es el tamaño del
-- archivo completo, no solo el del rango devuelto.
if #response.response < filesize then
options.filesize = filesize
options.partial = true
end
end
local relative_path = self.filename
print("Creating resource", relative_path)
local resource_hash = resource.create_sound_data(relative_path, options)
play_sound(self, resource_hash)
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
Puedes usar otros medios para cargar el fragmento inicial del archivo de sonido. Lo importante que debes recordar es que el resto de los fragmentos se cargan desde el sistema de recursos y sus proveedores de recursos. En este ejemplo, agregamos un nuevo proveedor de archivos (http) mediante un montaje de live update, llamando a liveupdate.add_mount().
Puedes encontrar un ejemplo funcional en https://github.com/defold/example-sound-streaming.
-- Consulta http_result() en el ejemplo anterior
local function load_web_sound(base_url, relative_path)
local url = base_url .. "/" .. relative_path
local headers = {}
-- Solicita la parte inicial del archivo
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 (_self, _name, _uri, _result)
-- cuando el montaje esté listo, podemos iniciar la solicitud para descargar el primer fragmento
load_web_sound(self.base_url, self.filename)
end)
end
function final(self)
liveupdate.remove_mount("webmount")
end
La cantidad de memoria consumida por los sonidos en runtime se controla con la configuración sound.stream_cache_size en game.project. Dado este límite, los datos de sonido cargados nunca lo superarán.
El fragmento inicial de cada archivo de sonido no puede desalojarse y ocupará la caché mientras los recursos estén cargados. El tamaño del fragmento inicial se controla con la configuración sound.stream_preload_size en game.project.
También puedes controlar el tamaño de cada fragmento de sonido cambiando la configuración sound.stream_chunk_size en game.project. Esto puede ayudarte a reducir aún más el tamaño de la caché de sonido si tienes muchos archivos de sonido cargados al mismo tiempo. Los archivos de sonido más pequeños que el tamaño del fragmento de sonido no se cargan en streaming y, si un nuevo fragmento no cabe en la caché, se desaloja el fragmento más antiguo.
El tamaño total de la caché de fragmentos de sonido debe ser mayor que el número de archivos de sonido cargados multiplicado por el tamaño del fragmento de streaming. De lo contrario, corres el riesgo de desalojar fragmentos nuevos en cada frame y los sonidos no se reproducirán correctamente.