jamulus-server.lisp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. (in-package :server)
  2. (defparameter *jamulus-server* nil)
  3. (defparameter *jamulus-recording-in-progress* nil)
  4. (defparameter *jamulus-recording-name* nil)
  5. (defparameter *jamulus-session* nil)
  6. (defun jamulus-current-recording-directory ()
  7. (namestring
  8. (merge-pathnames
  9. "quicklisp/local-projects/server/recordings/current-recording/"
  10. (user-homedir-pathname))))
  11. (defun jamulus-archive-directory ()
  12. (namestring
  13. (merge-pathnames
  14. "quicklisp/local-projects/server/recordings/archive/"
  15. (user-homedir-pathname))))
  16. (defun jamulus-open-server ()
  17. (unless *jamulus-server*
  18. (setf *jamulus-server*
  19. (sb-ext:run-program
  20. "/usr/local/bin/Jamulus"
  21. `("-s"
  22. "-n"
  23. "-R"
  24. ,(jamulus-current-recording-directory)) :output :stream :wait nil))
  25. (sleep 1)
  26. (sb-ext:process-kill *jamulus-server* sb-unix:sigusr2)
  27. ))
  28. (defun jamulus-start-recording (path)
  29. (unless *jamulus-recording-in-progress*
  30. (let ((session (cadr (pathname-directory path)))
  31. (recording-name (pathname-name path)))
  32. (setf *jamulus-recording-in-progress* t
  33. *jamulus-recording-name* (format nil "~a~a"
  34. recording-name
  35. (get-universal-time))
  36. *jamulus-session* session))
  37. (mapcar #'(lambda (d)
  38. (sb-ext:run-program "/bin/rm" `("-rf" ,(namestring d))))
  39. (uiop:subdirectories (jamulus-current-recording-directory)))
  40. (sb-ext:process-kill *jamulus-server* sb-unix:sigusr2)))
  41. (defun jamulus-stop-recording ()
  42. (when *jamulus-recording-in-progress*
  43. (sb-ext:process-kill *jamulus-server* sb-unix:sigusr2)
  44. (let* ((recdir (car (uiop:subdirectories (jamulus-current-recording-directory))))
  45. (files (uiop:directory-files recdir))
  46. (wavs (mapcan #'(lambda (f)
  47. (if (equal (pathname-type f) "wav")
  48. (list (namestring f))))
  49. files))
  50. (args (append (if (> (length wavs) 1)
  51. (list "-m"))
  52. wavs
  53. (list (namestring (merge-pathnames
  54. (format nil "~a.mp3" *jamulus-recording-name*)
  55. recdir))))))
  56. (unless (member-if #'(lambda (d)
  57. (string= (car (last (pathname-directory d)))
  58. *jamulus-session*))
  59. (uiop:subdirectories (jamulus-archive-directory)))
  60. (sb-ext:run-program "/bin/mkdir" (list (namestring
  61. (merge-pathnames
  62. *jamulus-session*
  63. (jamulus-archive-directory))))))
  64. (sb-ext:run-program "/usr/bin/sox" args)
  65. (sb-ext:run-program "/bin/mv" (list (namestring recdir)
  66. (namestring
  67. (merge-pathnames
  68. (format nil "~a/~a"
  69. *jamulus-session*
  70. *jamulus-recording-name*)
  71. (jamulus-archive-directory))))))
  72. (setf *jamulus-recording-in-progress* nil)))
  73. (defun jamulus-close-server ()
  74. (when *jamulus-server*
  75. (sb-ext:process-kill *jamulus-server* sb-unix:sigkill)
  76. (setf *jamulus-server* nil)))
  77. (defun jamulus-archive ()
  78. (let ((archive (make-hash-table :test 'equal)))
  79. (mapc #'(lambda (session-directory)
  80. (let ((session-name (car (last (pathname-directory session-directory)))))
  81. (setf (gethash session-name archive)
  82. (mapcar #'(lambda (recording-directory)
  83. (let ((recording-name (car (last (pathname-directory
  84. recording-directory)))))
  85. (append (list recording-name)
  86. (mapcar #'(lambda (f)
  87. (let ((file-name (pathname-name f))
  88. (file-type (pathname-type f)))
  89. (format nil
  90. "/recordings/archive/~a/~a/~a.~a"
  91. session-name
  92. recording-name
  93. file-name
  94. file-type)))
  95. (uiop:directory-files recording-directory)))))
  96. (uiop:subdirectories session-directory)))))
  97. (uiop:subdirectories (jamulus-archive-directory)))
  98. archive))
  99. (defun jamulus-controls (env)
  100. (let ((status (make-hash-table :test 'equal))
  101. (path-info (getf env :path-info)))
  102. (cond ((> (length (pathname-directory path-info)) 1)
  103. (jamulus-start-recording (format nil "~a/~a"
  104. (car (last (pathname-directory path-info)))
  105. (pathname-name path-info))))
  106. ((equal (pathname-name path-info) "open")
  107. (jamulus-open-server))
  108. ((equal (pathname-name path-info) "close")
  109. (jamulus-close-server))
  110. ((equal (pathname-name path-info) "stop_recording")
  111. (jamulus-stop-recording)))
  112. (setf (gethash "open" status) (if *jamulus-server* 'yason:true 'yason:false)
  113. (gethash "recording" status) (if *jamulus-recording-in-progress*
  114. 'yason:true 'yason:false)
  115. (gethash "archive" status) (jamulus-archive))
  116. `(200 (:content-type "application/json") (,(data:json status)))))