Added functions to be able to play on more renderers.
This commit is contained in:
@@ -15,3 +15,4 @@ compiled/
|
|||||||
# Dependency tracking files
|
# Dependency tracking files
|
||||||
*.dep
|
*.dep
|
||||||
|
|
||||||
|
/doc
|
||||||
|
|||||||
+158
-22
@@ -15,7 +15,9 @@
|
|||||||
(provide make-dlna-player
|
(provide make-dlna-player
|
||||||
dlna-player?
|
dlna-player?
|
||||||
dlna-player-play!
|
dlna-player-play!
|
||||||
|
dlna-player-play-uri!
|
||||||
dlna-player-set-next-file!
|
dlna-player-set-next-file!
|
||||||
|
dlna-player-set-next-uri!
|
||||||
dlna-player-pause!
|
dlna-player-pause!
|
||||||
dlna-player-resume!
|
dlna-player-resume!
|
||||||
dlna-player-stop!
|
dlna-player-stop!
|
||||||
@@ -39,7 +41,7 @@
|
|||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
(struct publication
|
(struct publication
|
||||||
(track uri metadata)
|
(track uri metadata owned? protocol-info mime-type)
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
(struct dlna-player
|
(struct dlna-player
|
||||||
@@ -214,10 +216,14 @@
|
|||||||
#:genre (dlna-track-info-genre track)
|
#:genre (dlna-track-info-genre track)
|
||||||
#:year (dlna-track-info-year track)
|
#:year (dlna-track-info-year track)
|
||||||
#:track (dlna-track-info-track track)
|
#:track (dlna-track-info-track track)
|
||||||
#:duration (dlna-track-info-duration track))))))
|
#:duration (dlna-track-info-duration track))
|
||||||
|
#t
|
||||||
|
#f
|
||||||
|
#f))))
|
||||||
|
|
||||||
(define (safe-unpublish! player item)
|
(define (safe-unpublish! player item)
|
||||||
(when item
|
(when (and item
|
||||||
|
(publication-owned? item))
|
||||||
(with-handlers ([exn:fail? (lambda (exception)
|
(with-handlers ([exn:fail? (lambda (exception)
|
||||||
(warn-dlna-player "Could not unpublish ~a: ~a" (publication-uri item) (exn-message exception))
|
(warn-dlna-player "Could not unpublish ~a: ~a" (publication-uri item) (exn-message exception))
|
||||||
(void))])
|
(void))])
|
||||||
@@ -271,7 +277,9 @@
|
|||||||
([exn:fail?
|
([exn:fail?
|
||||||
(lambda (exception)
|
(lambda (exception)
|
||||||
(err-dlna-player "Renderer operation failed: ~a" (exn-message exception))
|
(err-dlna-player "Renderer operation failed: ~a" (exn-message exception))
|
||||||
(set-reachable! player #f)
|
(set-reachable!
|
||||||
|
player
|
||||||
|
(exn:fail:upnp? exception))
|
||||||
(raise exception))])
|
(raise exception))])
|
||||||
(let ([result
|
(let ([result
|
||||||
(call-with-semaphore
|
(call-with-semaphore
|
||||||
@@ -339,7 +347,11 @@
|
|||||||
([exn:fail?
|
([exn:fail?
|
||||||
(lambda (exception)
|
(lambda (exception)
|
||||||
(warn-dlna-player "Could not refresh renderer state: ~a" (exn-message exception))
|
(warn-dlna-player "Could not refresh renderer state: ~a" (exn-message exception))
|
||||||
(set-reachable! player #f)
|
;; A SOAP/UPnP error is still a valid response from the renderer.
|
||||||
|
;; Only transport failures mean that it is unreachable.
|
||||||
|
(set-reachable!
|
||||||
|
player
|
||||||
|
(exn:fail:upnp? exception))
|
||||||
#f)])
|
#f)])
|
||||||
(call-with-semaphore
|
(call-with-semaphore
|
||||||
(dlna-player-transport-lock player)
|
(dlna-player-transport-lock player)
|
||||||
@@ -479,11 +491,8 @@
|
|||||||
(thread (lambda () (poll-player player))))
|
(thread (lambda () (poll-player player))))
|
||||||
player))
|
player))
|
||||||
|
|
||||||
(define (dlna-player-play! player file)
|
(define (play-publication! player item)
|
||||||
(info-dlna-player "Play requested file=~a" file)
|
(let ((track (publication-track item)))
|
||||||
(check-player 'dlna-player-play! player)
|
|
||||||
(let* ([track (player-track-info 'dlna-player-play! player file)]
|
|
||||||
[item (publish-track! player track)])
|
|
||||||
(with-handlers
|
(with-handlers
|
||||||
([exn:fail?
|
([exn:fail?
|
||||||
(lambda (exception)
|
(lambda (exception)
|
||||||
@@ -492,10 +501,33 @@
|
|||||||
(call-renderer
|
(call-renderer
|
||||||
player
|
player
|
||||||
(lambda ()
|
(lambda ()
|
||||||
|
(if (or (publication-protocol-info item)
|
||||||
|
(publication-mime-type item))
|
||||||
|
(media-renderer-play-resource!
|
||||||
|
(dlna-player-renderer player)
|
||||||
|
(publication-uri item)
|
||||||
|
#:protocol-info (publication-protocol-info item)
|
||||||
|
#:mime-type (publication-mime-type item)
|
||||||
|
#:title
|
||||||
|
(if track
|
||||||
|
(dlna-track-info-title track)
|
||||||
|
"Media")
|
||||||
|
#:artist
|
||||||
|
(and track (dlna-track-info-artist track))
|
||||||
|
#:album
|
||||||
|
(and track (dlna-track-info-album track))
|
||||||
|
#:genre
|
||||||
|
(and track (dlna-track-info-genre track))
|
||||||
|
#:year
|
||||||
|
(and track (dlna-track-info-year track))
|
||||||
|
#:track
|
||||||
|
(and track (dlna-track-info-track track))
|
||||||
|
#:duration
|
||||||
|
(and track (dlna-track-info-duration track)))
|
||||||
(media-renderer-play-uri!
|
(media-renderer-play-uri!
|
||||||
(dlna-player-renderer player)
|
(dlna-player-renderer player)
|
||||||
(publication-uri item)
|
(publication-uri item)
|
||||||
#:metadata (publication-metadata item))))
|
#:metadata (publication-metadata item)))))
|
||||||
(let ([old-current #f]
|
(let ([old-current #f]
|
||||||
[old-next #f])
|
[old-next #f])
|
||||||
(call-with-semaphore
|
(call-with-semaphore
|
||||||
@@ -514,7 +546,8 @@
|
|||||||
#f
|
#f
|
||||||
#f
|
#f
|
||||||
0
|
0
|
||||||
(dlna-track-info-duration track)
|
(and track
|
||||||
|
(dlna-track-info-duration track))
|
||||||
(dlna-info-volume (dlna-player-cached-info player))
|
(dlna-info-volume (dlna-player-cached-info player))
|
||||||
(dlna-info-muted? (dlna-player-cached-info player))
|
(dlna-info-muted? (dlna-player-cached-info player))
|
||||||
#t))
|
#t))
|
||||||
@@ -523,15 +556,44 @@
|
|||||||
(safe-unpublish! player old-next))
|
(safe-unpublish! player old-next))
|
||||||
(void))))
|
(void))))
|
||||||
|
|
||||||
(define (dlna-player-set-next-file! player file)
|
(define (dlna-player-play! player file)
|
||||||
(info-dlna-player "Set next track requested file=~a" file)
|
(info-dlna-player "Play requested file=~a" file)
|
||||||
(check-player 'dlna-player-set-next-file! player)
|
(check-player 'dlna-player-play! player)
|
||||||
(let* ([track
|
(let* ([track (player-track-info 'dlna-player-play! player file)]
|
||||||
(player-track-info
|
|
||||||
'dlna-player-set-next-file!
|
|
||||||
player
|
|
||||||
file)]
|
|
||||||
[item (publish-track! player track)])
|
[item (publish-track! player track)])
|
||||||
|
(play-publication! player item)))
|
||||||
|
|
||||||
|
(define (dlna-player-play-uri! player uri
|
||||||
|
#:metadata [metadata ""]
|
||||||
|
#:protocol-info [protocol-info #f]
|
||||||
|
#:mime-type [mime-type #f]
|
||||||
|
#:track [track #f])
|
||||||
|
(info-dlna-player "Play requested URI=~a" uri)
|
||||||
|
(check-player 'dlna-player-play-uri! player)
|
||||||
|
(unless (and (string? uri)
|
||||||
|
(not (string=? (string-trim uri) "")))
|
||||||
|
(raise-argument-error
|
||||||
|
'dlna-player-play-uri!
|
||||||
|
"non-empty-string?"
|
||||||
|
uri))
|
||||||
|
(unless (or (not track)
|
||||||
|
(dlna-track-info? track))
|
||||||
|
(raise-argument-error
|
||||||
|
'dlna-player-play-uri!
|
||||||
|
"(or/c #f dlna-track-info?)"
|
||||||
|
track))
|
||||||
|
(for ([value (in-list (list protocol-info mime-type))])
|
||||||
|
(unless (or (not value) (string? value))
|
||||||
|
(raise-argument-error
|
||||||
|
'dlna-player-play-uri!
|
||||||
|
"(or/c #f string?)"
|
||||||
|
value)))
|
||||||
|
(play-publication!
|
||||||
|
player
|
||||||
|
(publication track uri metadata #f protocol-info mime-type)))
|
||||||
|
|
||||||
|
(define (set-next-publication! player item)
|
||||||
|
(let ((track (publication-track item)))
|
||||||
(with-handlers
|
(with-handlers
|
||||||
([exn:fail?
|
([exn:fail?
|
||||||
(lambda (exception)
|
(lambda (exception)
|
||||||
@@ -540,10 +602,33 @@
|
|||||||
(call-renderer
|
(call-renderer
|
||||||
player
|
player
|
||||||
(lambda ()
|
(lambda ()
|
||||||
|
(if (or (publication-protocol-info item)
|
||||||
|
(publication-mime-type item))
|
||||||
|
(media-renderer-set-next-resource!
|
||||||
|
(dlna-player-renderer player)
|
||||||
|
(publication-uri item)
|
||||||
|
#:protocol-info (publication-protocol-info item)
|
||||||
|
#:mime-type (publication-mime-type item)
|
||||||
|
#:title
|
||||||
|
(if track
|
||||||
|
(dlna-track-info-title track)
|
||||||
|
"Media")
|
||||||
|
#:artist
|
||||||
|
(and track (dlna-track-info-artist track))
|
||||||
|
#:album
|
||||||
|
(and track (dlna-track-info-album track))
|
||||||
|
#:genre
|
||||||
|
(and track (dlna-track-info-genre track))
|
||||||
|
#:year
|
||||||
|
(and track (dlna-track-info-year track))
|
||||||
|
#:track
|
||||||
|
(and track (dlna-track-info-track track))
|
||||||
|
#:duration
|
||||||
|
(and track (dlna-track-info-duration track)))
|
||||||
(media-renderer-set-next-uri!
|
(media-renderer-set-next-uri!
|
||||||
(dlna-player-renderer player)
|
(dlna-player-renderer player)
|
||||||
(publication-uri item)
|
(publication-uri item)
|
||||||
#:metadata (publication-metadata item))))
|
#:metadata (publication-metadata item)))))
|
||||||
(let ([old-next #f])
|
(let ([old-next #f])
|
||||||
(call-with-semaphore
|
(call-with-semaphore
|
||||||
(dlna-player-cache-lock player)
|
(dlna-player-cache-lock player)
|
||||||
@@ -560,6 +645,46 @@
|
|||||||
(safe-unpublish! player old-next))
|
(safe-unpublish! player old-next))
|
||||||
(void))))
|
(void))))
|
||||||
|
|
||||||
|
(define (dlna-player-set-next-file! player file)
|
||||||
|
(info-dlna-player "Set next track requested file=~a" file)
|
||||||
|
(check-player 'dlna-player-set-next-file! player)
|
||||||
|
(let* ([track
|
||||||
|
(player-track-info
|
||||||
|
'dlna-player-set-next-file!
|
||||||
|
player
|
||||||
|
file)]
|
||||||
|
[item (publish-track! player track)])
|
||||||
|
(set-next-publication! player item)))
|
||||||
|
|
||||||
|
(define (dlna-player-set-next-uri! player uri
|
||||||
|
#:metadata [metadata ""]
|
||||||
|
#:protocol-info [protocol-info #f]
|
||||||
|
#:mime-type [mime-type #f]
|
||||||
|
#:track [track #f])
|
||||||
|
(info-dlna-player "Set next track requested URI=~a" uri)
|
||||||
|
(check-player 'dlna-player-set-next-uri! player)
|
||||||
|
(unless (and (string? uri)
|
||||||
|
(not (string=? (string-trim uri) "")))
|
||||||
|
(raise-argument-error
|
||||||
|
'dlna-player-set-next-uri!
|
||||||
|
"non-empty-string?"
|
||||||
|
uri))
|
||||||
|
(unless (or (not track)
|
||||||
|
(dlna-track-info? track))
|
||||||
|
(raise-argument-error
|
||||||
|
'dlna-player-set-next-uri!
|
||||||
|
"(or/c #f dlna-track-info?)"
|
||||||
|
track))
|
||||||
|
(for ([value (in-list (list protocol-info mime-type))])
|
||||||
|
(unless (or (not value) (string? value))
|
||||||
|
(raise-argument-error
|
||||||
|
'dlna-player-set-next-uri!
|
||||||
|
"(or/c #f string?)"
|
||||||
|
value)))
|
||||||
|
(set-next-publication!
|
||||||
|
player
|
||||||
|
(publication track uri metadata #f protocol-info mime-type)))
|
||||||
|
|
||||||
(define (dlna-player-pause! player)
|
(define (dlna-player-pause! player)
|
||||||
(info-dlna-player "Pause requested")
|
(info-dlna-player "Pause requested")
|
||||||
(check-player 'dlna-player-pause! player)
|
(check-player 'dlna-player-pause! player)
|
||||||
@@ -595,10 +720,21 @@
|
|||||||
(define (dlna-player-stop! player)
|
(define (dlna-player-stop! player)
|
||||||
(info-dlna-player "Stop requested")
|
(info-dlna-player "Stop requested")
|
||||||
(check-player 'dlna-player-stop! player)
|
(check-player 'dlna-player-stop! player)
|
||||||
|
(with-handlers
|
||||||
|
([exn:fail:upnp?
|
||||||
|
(lambda (exception)
|
||||||
|
(unless
|
||||||
|
(equal?
|
||||||
|
(exn:fail:upnp-code exception)
|
||||||
|
"701")
|
||||||
|
(raise exception))
|
||||||
|
(dbg-dlna-player
|
||||||
|
"Renderer was already in a state where Stop is unavailable"))])
|
||||||
(call-renderer
|
(call-renderer
|
||||||
player
|
player
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(media-renderer-stop! (dlna-player-renderer player))))
|
(media-renderer-stop!
|
||||||
|
(dlna-player-renderer player)))))
|
||||||
(update-cache!
|
(update-cache!
|
||||||
player
|
player
|
||||||
(lambda (info)
|
(lambda (info)
|
||||||
|
|||||||
@@ -60,6 +60,37 @@ Publishes and preloads the file with @tt{SetNextAVTransportURI}. Replacing the
|
|||||||
next file removes the previous next-file publication.
|
next file removes the previous next-file publication.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@defproc[(dlna-player-play-uri!
|
||||||
|
[player dlna-player?]
|
||||||
|
[uri string?]
|
||||||
|
[#:metadata metadata string? ""]
|
||||||
|
[#:protocol-info protocol-info (or/c #f string?) #f]
|
||||||
|
[#:mime-type mime-type (or/c #f string?) #f]
|
||||||
|
[#:track track (or/c #f dlna-track-info?) #f])
|
||||||
|
void?]{
|
||||||
|
|
||||||
|
Installs an existing HTTP media URI directly on the renderer and starts
|
||||||
|
playback. The URI is not published or owned by this player. Optional
|
||||||
|
DIDL-Lite metadata and track information are retained in the player state.
|
||||||
|
When @racket[protocol-info] or @racket[mime-type] is supplied, the resource
|
||||||
|
capabilities are resolved by @racketmodname[racket-upnp] immediately before
|
||||||
|
playback and matching DIDL-Lite is generated automatically. In that case
|
||||||
|
@racket[metadata] is ignored.
|
||||||
|
}
|
||||||
|
|
||||||
|
@defproc[(dlna-player-set-next-uri!
|
||||||
|
[player dlna-player?]
|
||||||
|
[uri string?]
|
||||||
|
[#:metadata metadata string? ""]
|
||||||
|
[#:protocol-info protocol-info (or/c #f string?) #f]
|
||||||
|
[#:mime-type mime-type (or/c #f string?) #f]
|
||||||
|
[#:track track (or/c #f dlna-track-info?) #f])
|
||||||
|
void?]{
|
||||||
|
|
||||||
|
Preloads an existing HTTP media URI with @tt{SetNextAVTransportURI}. Replacing
|
||||||
|
it never attempts to remove the external resource.
|
||||||
|
}
|
||||||
|
|
||||||
@defproc[(dlna-player-pause! [player dlna-player?]) void?]
|
@defproc[(dlna-player-pause! [player dlna-player?]) void?]
|
||||||
@defproc[(dlna-player-resume! [player dlna-player?]) void?]
|
@defproc[(dlna-player-resume! [player dlna-player?]) void?]
|
||||||
@defproc[(dlna-player-stop! [player dlna-player?]) void?]
|
@defproc[(dlna-player-stop! [player dlna-player?]) void?]
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
(check-equal? (dlna-info-position info) 12)
|
(check-equal? (dlna-info-position info) 12)
|
||||||
(check-equal? (dlna-info-volume info) 35)
|
(check-equal? (dlna-info-volume info) 35)
|
||||||
(check-true (dlna-info-reachable? info))
|
(check-true (dlna-info-reachable? info))
|
||||||
|
(check-true (procedure? dlna-player-play-uri!))
|
||||||
|
(check-true (procedure? dlna-player-set-next-uri!))
|
||||||
|
|
||||||
(check-exn exn:fail:contract?
|
(check-exn exn:fail:contract?
|
||||||
(lambda () (make-dlna-player #f)))
|
(lambda () (make-dlna-player #f)))
|
||||||
|
|||||||
Reference in New Issue
Block a user