Integración móvil
Usa la API de ADN con claves API Client-Side desde tu app iOS, Android o Flutter. Reproduce y sube archivos con elementos multimedia nativos.
Ideal para
Apps iOS, Android y Flutter. La configuración tarda unos 30 minutos.
Reproducir pistas
Crea sesiones de reproducción y reproduce audio con players multimedia nativos.
Llama a la API de reproducción de ADN directamente desde tu app móvil usando una clave API Client-Side. Crea sesiones de reproducción, obtén URLs de variante firmadas y reproduce audio con players multimedia nativos.
1. Crear una clave API Client-Side Player
En Settings → API Keys, crea una clave Client-Side Player. Limítala a las variantes y el contenido al que tu app móvil debería acceder.
2. Crear una sesión de reproducción
import Foundation
struct PlaySessionRequest: Encodable {
let collectionId: String
let variants: [String]
let isDownloadable: Bool
let expiresIn: Int
enum CodingKeys: String, CodingKey {
case collectionId = "collection_id"; case variants
case isDownloadable = "is_downloadable"; case expiresIn = "expires_in"
}
}
struct PlaySessionResponse: Decodable {
let playSessionId: String
let tracks: [Track]
enum CodingKeys: String, CodingKey { case playSessionId = "play_session_id"; case tracks }
struct Track: Decodable { let id: String }
}
func createPlaySession() async throws -> (playSessionId: String, tracks: [PlaySessionResponse.Track]) {
var request = URLRequest(url: URL(string: "https://api.audiodelivery.net/v1/play_session/collection")!)
request.httpMethod = "POST"
request.setValue("Bearer CLIENT-SIDE-PLAYER-API-KEY", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
request.httpBody = try encoder.encode(PlaySessionRequest(
collectionId: "COLLECTION-ID", variants: ["hq", "lq"], isDownloadable: false, expiresIn: 3600))
let (data, _) = try await URLSession.shared.data(for: request)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let session = try decoder.decode(PlaySessionResponse.self, from: data)
return (session.playSessionId, session.tracks)
} 3. Obtener URLs de variante de pista
struct TrackVariantsResponse: Decodable {
let variants: [Variant]
struct Variant: Decodable {
let url: String
let variant: VariantIndex
struct VariantIndex: Decodable { let id: String }
}
}
// No auth needed — the session ID acts as a bearer token
func getAudioUrl(playSessionId: String, trackId: String) async throws -> String {
let url = URL(string: "https://api.audiodelivery.net/v1/play/\(playSessionId)/\(trackId)")!
let (data, _) = try await URLSession.shared.data(from: url)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let res = try decoder.decode(TrackVariantsResponse.self, from: data)
let hq = res.variants.first { $0.variant.id == "hq" }!
return hq.url
} 4. Reproducir con el player nativo
import AVFoundation
let player = AVPlayer(url: URL(string: audioUrl)!)
player.play() La URL firmada funciona con cualquier player multimedia nativo. ADN gestiona la entrega CDN y la verificación de URL.
Datos de forma de onda
ADN genera automáticamente datos de forma de onda RMS normalizados (320 muestras) para cada pista.
El campo levels en la respuesta de la pista contiene los datos — úsalos para renderizar formas de onda
en tu propio player, o genera formas de onda personalizadas mediante el tipo de variante Audio Analysis.
Imágenes de portada y colores de tema
ADN analiza cada pista subida en busca de arte de portada incrustado y lo pone disponible como cover_image
en la respuesta de la pista (en tamaños icon/small/regular/large). También puedes subir una imagen de portada
por separado vía la API. Cuando hay una imagen de portada, ADN extrae una paleta de colores
y selecciona un player_color principal — úsalos para estilizar la UI de tu player. Junto a él,
las respuestas incluyen player_color_light y player_color_dark, variantes ajustadas por contraste
para dibujar el color sobre fondos claros y oscuros respectivamente. El array completo
theme contiene todos los colores extraídos con valores hex, área, luminosidad y saturación.
Subir pistas
Sube archivos de audio desde apps nativas usando la API de subida de ADN.
Llama a la API de subida de ADN directamente desde tu app móvil usando una clave API Client-Side. Crea sesiones de subida, obtén URLs prefirmadas y sube archivos de audio — todo desde código nativo.
1. Crear una clave API Client-Side Upload
Inicia sesión en ADN, ve a Settings → API Keys y crea una clave Client-Side Upload. Limítala a la colección a la que tu app debería subir.
2. Crear una sesión de subida
import Foundation
struct UploadSessionRequest: Encodable {
let collectionId: String
let expiresIn: Int
enum CodingKeys: String, CodingKey { case collectionId = "collection_id"; case expiresIn = "expires_in" }
}
struct UploadSessionResponse: Decodable {
let uploadSession: UploadSession
enum CodingKeys: String, CodingKey { case uploadSession = "upload_session" }
struct UploadSession: Decodable { let id: String }
}
func createUploadSession() async throws -> String {
var request = URLRequest(url: URL(string: "https://api.audiodelivery.net/v1/upload_session")!)
request.httpMethod = "POST"
request.setValue("Bearer CLIENT-SIDE-UPLOAD-API-KEY", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
request.httpBody = try encoder.encode(UploadSessionRequest(collectionId: "COLLECTION-ID", expiresIn: 3600))
let (data, _) = try await URLSession.shared.data(for: request)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let session = try decoder.decode(UploadSessionResponse.self, from: data)
return session.uploadSession.id
} 3. Obtener una URL de subida de pista
struct TrackUploadRequest: Encodable {
let fileName: String
enum CodingKeys: String, CodingKey { case fileName = "file_name" }
}
struct TrackUploadResponse: Decodable {
let trackUpload: TrackUpload
enum CodingKeys: String, CodingKey { case trackUpload = "track_upload" }
struct TrackUpload: Decodable { let uploadUrl: String; let method: String
enum CodingKeys: String, CodingKey { case uploadUrl = "upload_url"; case method }
}
}
func getTrackUploadUrl(sessionId: String) async throws -> (url: String, method: String) {
var request = URLRequest(url: URL(string: "https://api.audiodelivery.net/v1/upload/\(sessionId)/track")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
request.httpBody = try encoder.encode(TrackUploadRequest(fileName: "recording.m4a"))
let (data, _) = try await URLSession.shared.data(for: request)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let res = try decoder.decode(TrackUploadResponse.self, from: data)
return (res.trackUpload.uploadUrl, res.trackUpload.method)
} 4. Subir el archivo
// Prefer streaming for large files instead of loading into memory
func uploadAudio(fileURL: URL, uploadURL: URL, method: String) async throws {
var request = URLRequest(url: uploadURL)
request.httpMethod = method
request.setValue("audio/mp4", forHTTPHeaderField: "Content-Type")
request.httpBodyStream = InputStream(url: fileURL)
let (_, uploadResponse) = try await URLSession.shared.data(for: request)
let httpResponse = uploadResponse as! HTTPURLResponse
print("Upload status: \(httpResponse.statusCode)") // 200 on success
} Repite los pasos 3 y 4 por cada archivo — cada pista necesita su propia solicitud de subida y URL firmada. También puedes incluir un objeto anidado track al crear la sesión para crear la primera pista de antemano, y luego usar el paso 3 para cualquier archivo adicional.
5. Esperar a que la pista esté lista
El procesamiento comienza automáticamente después de la subida. Antes de reproducir la pista, espera hasta que esté lista — consulta GET /v1/track/{track_id} hasta que track.track_status_id sea ready, o configura un webhook (paso siguiente) para recibir notificaciones en lugar de hacer polling.
6. Opcional: Webhooks
Añade un webhook en Settings → Webhook para recibir notificaciones cuando una pista alcanza un resultado terminal (ready, incomplete, error o init_error) y cuando su conjunto completo de archivos está listo. Consulta la documentación del webhook Track Processing.
Imágenes de portada
ADN analiza automáticamente las pistas subidas en busca de arte de portada incrustado. También puedes subir una imagen de
portada por separado vía la Covers API. Cuando hay una imagen, ADN extrae colores (disponibles como theme)
que se pueden usar para estilizar la UI de tu player.