#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"] #: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) (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") (res ((protocolInfo ,protocol-info) ,@(if duration `((duration ,(duration->string 'didl-lite-audio-item duration))) '()) ,@(if size `((size ,(number->string size))) '())) ,uri)))))