Files
racket-upnp/scribblings/media-file-server.scrbl
T
2026-10-30 10:41:56 +01:00

164 lines
4.3 KiB
Racket

#lang scribble/manual
@(require
(for-label
racket/base
(file "../didl-lite.rkt")
(file "../media-file-server.rkt")))
@title{Publishing Media Files}
@defmodule[racket-upnp/media-file-server]
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.
At info log level, each published transfer reports its start and completion or
interruption, including client address, HTTP method, requested range and elapsed
time. No publication lock is held while the response is being streamed.
@defproc[(media-file-server? [value any/c]) boolean?]{
Returns @racket[#t] when @racket[value] is a media file server.
}
@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.