Files
2026-07-31 10:23:23 +02:00

92 lines
3.2 KiB
Racket

#lang racket/base
;; Generate the DIDL-Lite description passed to AVTransport actions.
(require racket/format
xml)
(provide didl-lite-audio-item)
(define (check-string who value)
(unless (string? value)
(raise-argument-error who "string?" value)))
(define (duration->string who duration)
(unless (and (rational? duration)
(not (negative? duration)))
(raise-argument-error who "nonnegative-real?" duration))
(let* ([seconds (inexact->exact (floor duration))]
[hours (quotient seconds 3600)]
[remaining (remainder seconds 3600)]
[minutes (quotient remaining 60)])
(format "~a:~a:~a"
hours
(~r minutes #:min-width 2 #:pad-string "0")
(~r (remainder remaining 60)
#:min-width 2
#:pad-string "0"))))
(define (didl-lite-audio-item uri
#:protocol-info protocol-info
#:title [title "Media"]
#:artist [artist #f]
#:album [album #f]
#:genre [genre #f]
#:year [year #f]
#:track [track #f]
#:duration [duration #f]
#:size [size #f]
#:id [id "0"]
#:parent-id [parent-id "0"])
(check-string 'didl-lite-audio-item uri)
(check-string 'didl-lite-audio-item protocol-info)
(check-string 'didl-lite-audio-item title)
(check-string 'didl-lite-audio-item id)
(check-string 'didl-lite-audio-item parent-id)
(for ([value (in-list (list artist album genre))])
(unless (or (not value) (string? value))
(raise-argument-error
'didl-lite-audio-item
"(or/c #f string?)"
value)))
(for ([value (in-list (list year track))])
(unless (or (not value) (exact-nonnegative-integer? value))
(raise-argument-error
'didl-lite-audio-item
"(or/c #f exact-nonnegative-integer?)"
value)))
(unless (or (not size)
(exact-nonnegative-integer? size))
(raise-argument-error
'didl-lite-audio-item
"(or/c #f exact-nonnegative-integer?)"
size))
(xexpr->string
`(DIDL-Lite
((xmlns "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/")
(xmlns:dc "http://purl.org/dc/elements/1.1/")
(xmlns:upnp "urn:schemas-upnp-org:metadata-1-0/upnp/"))
(item
((id ,id)
(parentID ,parent-id)
(restricted "1"))
(dc:title () ,title)
(upnp:class () "object.item.audioItem.musicTrack")
,@(if artist `((upnp:artist () ,artist)) '())
,@(if album `((upnp:album () ,album)) '())
,@(if genre `((upnp:genre () ,genre)) '())
,@(if year `((dc:date () ,(number->string year))) '())
,@(if track
`((upnp:originalTrackNumber () ,(number->string track)))
'())
(res
((protocolInfo ,protocol-info)
,@(if duration
`((duration
,(duration->string 'didl-lite-audio-item duration)))
'())
,@(if size
`((size ,(number->string size)))
'()))
,uri)))))