Streaming architecture
The Go server owns authorization and byte-range behavior. The Expo client supplies the authenticated media URL to the native audio player.
func media(w http.ResponseWriter, r *http.Request) {
file, meta, err := store.Open(r.Context(), actor(r), mediaID(r))
if err != nil {
http.Error(w, "media unavailable", http.StatusNotFound)
return
}
defer file.Close()
http.ServeContent(w, r, meta.Name, meta.Modified, file)
}export async function playableMediaURL(mediaID: string) {
const token = await authToken();
return {
uri: `${apiBaseURL}/api/v1/media/${mediaID}`,
headers: { Authorization: `Bearer ${token}` },
};
}Why byte ranges matter
Section titled “Why byte ranges matter”Native players seek by requesting only the required part of a large audiobook. http.ServeContent implements standard range responses without a custom streaming abstraction.