(define mpg-123 "/afs/wsi/ppc_macx72/bin/mpg123") (define test-file "/Users/knauel/tmp/playlists/popa-chubby-devils-guitar.m3u") (define-record-type state :state (make-state unplayed played) state? (unplayed state-unplayed set-state-unplayed!) (played state-played set-state-played!)) (define (run-mpg-123 song) 'foo) (define (wait-for-mpg-123-termination proc channel) (spawn (lambda () (send channel (wait proc))))) (define (make-mpg-123-controller song) (let ((stop-channel (make-channel)) (finished-channel (make-channel)) (status-channel (make-channel))) (spawn (lambda () (call-with-values (lambda () (run-mpg-123 (song-url song))) (lambda (port proc) (let ((int-finished-ch (make-channel))) (wait-for-mpg-123-termination proc int-finished-ch) (select (wrap (receive-rv stop-channel) (lambda (ignore) (signal-process proc signal/quit) (send status-channel 'killed))) (wrap (receive-rv int-finished-ch) (lambda (status) (send status-channel status))))))))) (values stop-channel status-channel))) (define (load-m3u-file! file-name state) (set-state-played! state '()) (set-state-unplayed! state (read-m3u-file file-name))) (define (play-song song state) (set-state-unplayed! state (delq song (state-unplayed state))) (set-state-played! state (cons song (state-played state))) (make-mpg-123-controller song)) (define (stop-mpg-123 stop-channel status-channel) (if stop-channel (send stop-channel 'shut-up!)) (receive status-channel)) (define (layout-song width song) (cut-to-size width (if (song-ext3-info? song) (song-title song) (song-url song)))) (define (make-playlist songs num-cols num-lines) (make-select-list (map (lambda (s) (make-unmarked-text-element s #t (layout-song num-cols s))) songs) num-lines)) (define (make-netjuke-viewer file-name buffer) (let ((state (make-state '() '())) (stop-channel #f) (status-channel #f) ;; GUI stuff (num-cols (- (result-buffer-num-cols buffer) 1)) (num-lines (- (result-buffer-num-lines buffer) 1)) (select-list #f)) (define (start-playing song) (call-with-values (lambda () (play-song song)) (lambda (stop-ch status-ch) (set! stop-channel stop-ch) (set! status-channel status-ch)))) (define (stop-playing) (stop-mpg-123 stop-channel status-channel)) (lambda (message) (case message ((paint) (lambda (self win buffer have-focus?) (if select-list (paint-selection-list-at select-list 0 0 win num-cols have-focus?)) self)) ((key-press) (lambda (self key control-x-pressed?) (load-m3u-file! test-file state) (set! select-list (make-playlist (state-unplayed state) num-cols num-lines)) self)) (else (error "netjuke viewer unknown message" message)))))) (register-plugin! (make-view-plugin make-netjuke-viewer (lambda (val) (and (string? val) (string=? val "netjuke"))))) ; (define (get-real-url netjuke-url) ; (let ((headers (run/strings (curl -x "" -s -G -I ,netjuke-url)))) ; (fold-right ; (lambda (header found) ; (if-match ; (regexp-search (rx (: bos "Location: ") ; (submatch (+ any))) ; header) ; (whole new-url) ; new-url ; found)) ; #f ; headers))) ; (define (play-track real-url) ; (run (,mpg-123 ,real-url))) ; (define (random-play netjuke-m3u-file) ; (let ((nj-urls (read-m3u-file netjuke-m3u-file))) ; (let lp ((track-list nj-urls)) ; (cond ; ((null? track-list) ; (display "Playlist empty") ; (newline)) ; (else ; (let ((track ; (list-ref track-list ; (modulo (random-integer) (length track-list))))) ; (display "Playing ") ; (display track) ; (newline) ; (play-track (get-real-url track)) ; (lp (delete track track-list)))))))) ; (define (real-urls urls) ; (append-map ; (lambda (url) ; (let ((headers (run/strings (curl -x "" -s -G -I ,url)))) ; (filter-map ; (lambda (str) ; (if-match ; (regexp-search ; (rx (: bos "Location: " (submatch (+ any )))) str) ; (whole new-url) ; new-url ; #f)) ; headers))) ; urls)) ; (define (main args) ; (if (not (= (length args) 2)) ; (error "Need exactly one file argument")) ; (let ((file-name (cadr args))) ; (random-play file-name)))