Files
racket-upnp/scribblings/media-file-server.scrbl
2026-07-31 10:23:23 +02:00

156 lines
4.0 KiB
Racket

#lang scribble/manual
@(require
(for-label
racket/base
(file "../didl-lite.rkt")
(file "../media-file-server.rkt")))
@title{Publishing Media Files}
@defmodule[(file "../media-file-server.rkt")]
This module publishes local files through a small Racket web server. The
underlying Racket file dispatcher streams files and supports both @tt{HEAD}
requests and HTTP byte ranges. Byte ranges are important for media-renderer
probing and seeking.
@defproc[(start-media-file-server
[url string?]
[#:listen-ip listen-ip (or/c #f string?) #f])
media-file-server?]{
Starts a server for the HTTP origin and path prefix in @racket[url].
The URL must be an absolute @tt{http://} URL. A trailing slash is added when
needed.
When @racket[listen-ip] is @racket[#f], the server listens on all local
interfaces. Supply a local address, such as @tt{10.7.3.118}, to restrict the
listener to that interface.
}
@defproc[(media-file-server-url
[server media-file-server?])
string?]{
Returns the normalized base URL of @racket[server].
}
@defproc[(media-file-server-publish!
[server media-file-server?]
[file path-string?]
[url string?]
[#:mime-type mime-type (or/c #f bytes? string?) #f])
string?]{
Publishes @racket[file] at @racket[url] and returns the absolute URL.
The URL may be relative to the server URL:
@racketblock[
(define uri
(media-file-server-publish!
files
"C:/muziek/test.flac"
"test.flac"))
]
It may also be the complete URL, provided that its origin and path prefix match
the server:
@racketblock[
(media-file-server-publish!
files
"C:/muziek/test.flac"
"http://10.7.3.118:8080/media/test.flac")
]
The MIME type is inferred for common audio, video, and image extensions.
Use @racket[#:mime-type] to override it.
}
@defproc[(media-file-server-unpublish!
[server media-file-server?]
[url string?])
void?]{
Removes the URL mapping. Requests that are already in progress may still
finish.
}
@defproc[(media-file-server-didl-lite
[server media-file-server?]
[url string?]
[#:title title (or/c #f string?) #f]
[#:artist artist (or/c #f string?) #f]
[#:album album (or/c #f string?) #f]
[#:genre genre (or/c #f string?) #f]
[#:year year (or/c #f exact-nonnegative-integer?) #f]
[#:track track (or/c #f exact-nonnegative-integer?) #f]
[#:duration duration (or/c #f nonnegative-real?) #f]
[#:id id string? "0"]
[#:parent-id parent-id string? "0"])
string?]{
Returns DIDL-Lite metadata for a URL previously installed with
@racket[media-file-server-publish!]. The MIME type, file size, and
@tt{DLNA.ORG_OP=01} byte-range capability are taken from the actual
publication. The file name is used as the title when @racket[title] is
@racket[#f].
Pass the result as @racket[#:metadata] or @racket[#:next-metadata] to the
media-renderer functions. Supplying the duration is recommended because some
renderers use it when deciding whether time seeking is available.
}
@defproc[(media-file-server-stop!
[server media-file-server?])
void?]{
Stops the web server. Repeated calls have no effect.
}
@section{Playing local files}
@racketblock[
(define files
(start-media-file-server
"http://10.7.3.118:8080/media/"
#:listen-ip "10.7.3.118"))
(define first-uri
(media-file-server-publish!
files
"C:/muziek/first.flac"
"first.flac"))
(define second-uri
(media-file-server-publish!
files
"C:/muziek/second.flac"
"second.flac"))
(define first-metadata
(media-file-server-didl-lite
files
first-uri
#:title "First track"
#:duration 639))
(define second-metadata
(media-file-server-didl-lite
files
second-uri
#:title "Second track"
#:duration 242))
(media-renderer-play-uri!
renderer
first-uri
#:metadata first-metadata
#:next-uri second-uri
#:next-metadata second-metadata)
]
Keep the URLs published until the renderer has finished reading them.