media.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "os/exec"
  6. // osc
  7. "github.com/hypebeast/go-osc/osc"
  8. )
  9. // Base structure for audiovisual media.
  10. // Media is simply a file containing audio and video material.
  11. type Media struct {
  12. active bool
  13. cmd *exec.Cmd
  14. args []string
  15. }
  16. // Interface for Media type structs
  17. type MediaPlayer interface {
  18. play()
  19. stop()
  20. }
  21. // Run executable
  22. func run(name string, args ...string) *exec.Cmd {
  23. // Find executable
  24. //path, err := exec.LookPath(name)
  25. //if err != nil {
  26. // log.Printf("can't find '%s'\n", name)
  27. // return nil
  28. //}
  29. //println("got path")
  30. cmd := exec.Command(name, args...)
  31. if err := cmd.Run(); err != nil {
  32. log.Print(err)
  33. //log.Print(path, args)
  34. return nil
  35. }
  36. //println("got cmd running")
  37. return cmd
  38. }
  39. // Run executable
  40. func (player *Media) run(name string, args ...string) {
  41. // Find executable
  42. //path, err := exec.LookPath(name)
  43. //if err != nil {
  44. // log.Printf("can't find '%s'\n", name)
  45. // return nil
  46. //}
  47. //println("got path")
  48. player.cmd = exec.Command(name, args...)
  49. if err := player.cmd.Run(); err != nil {
  50. log.Print(err)
  51. //log.Print(path, args)
  52. }
  53. //println("got cmd running")
  54. }
  55. // Play media file via mpv, osc message sets the file path
  56. func (player *Media) play(msg *osc.Message) {
  57. if player.active {
  58. log.Print("please stop current player before playing another")
  59. log.Print(player.cmd)
  60. return
  61. }
  62. uri := getOSC[string](msg)
  63. osc.PrintMessage(msg)
  64. if uri == "" {
  65. log.Print("player won't play without uri")
  66. return
  67. }
  68. player.active = true
  69. // you can route audio directly through alsa/hdmi but beware of clipping
  70. //run(player, "mpv", "-fs", "--audio-device=alsa/hdmi", "--volume=25", uri)
  71. args := append(player.args, uri)
  72. player.run(args[0], args[1:]...)
  73. player.active = false
  74. }
  75. // Stop the player by shutting down MPV
  76. func (player *Media) stop(msg *osc.Message) {
  77. player.quit()
  78. }
  79. // Change volume using amixer command
  80. func (player *Media) volume(msg *osc.Message) {
  81. level := getOSC[float32](msg)
  82. run("amixer", "-q", "sset", "Master", fmt.Sprintf("%.2f%%", level*100.0))
  83. }
  84. func (player *Media) quit() {
  85. if !player.active {
  86. log.Print("can't kill player if it ain't running")
  87. return
  88. }
  89. if err := player.cmd.Process.Kill(); err != nil {
  90. log.Print("failed to kill process: ", err)
  91. }
  92. player.active = false
  93. }
  94. func NewMPV() *Media {
  95. media := new(Media)
  96. media.args = []string{"mpv", "-fs"}
  97. return media
  98. }
  99. func NewXLEmulator() *Media {
  100. media := new(Media)
  101. media.args = []string{"atari800", "-stretch", "3"}
  102. return media
  103. }