player_event_handler.rs 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. use librespot::playback::player::PlayerEvent;
  2. use log::info;
  3. use std::collections::HashMap;
  4. use std::io;
  5. use std::process::Command;
  6. use tokio_process::{Child, CommandExt};
  7. use futures::Future;
  8. use librespot::playback::player::SinkStatus;
  9. fn run_program(program: &str, env_vars: HashMap<&str, String>) -> io::Result<Child> {
  10. let mut v: Vec<&str> = program.split_whitespace().collect();
  11. info!("Running {:?} with environment variables {:?}", v, env_vars);
  12. Command::new(&v.remove(0))
  13. .args(&v)
  14. .envs(env_vars.iter())
  15. .spawn_async()
  16. }
  17. pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> Option<io::Result<Child>> {
  18. let mut env_vars = HashMap::new();
  19. match event {
  20. PlayerEvent::Changed {
  21. old_track_id,
  22. new_track_id,
  23. } => {
  24. env_vars.insert("PLAYER_EVENT", "change".to_string());
  25. env_vars.insert("OLD_TRACK_ID", old_track_id.to_base62());
  26. env_vars.insert("TRACK_ID", new_track_id.to_base62());
  27. }
  28. PlayerEvent::Started { track_id, .. } => {
  29. env_vars.insert("PLAYER_EVENT", "start".to_string());
  30. env_vars.insert("TRACK_ID", track_id.to_base62());
  31. }
  32. PlayerEvent::Stopped { track_id, .. } => {
  33. env_vars.insert("PLAYER_EVENT", "stop".to_string());
  34. env_vars.insert("TRACK_ID", track_id.to_base62());
  35. }
  36. PlayerEvent::Playing {
  37. track_id,
  38. duration_ms,
  39. position_ms,
  40. ..
  41. } => {
  42. env_vars.insert("PLAYER_EVENT", "playing".to_string());
  43. env_vars.insert("TRACK_ID", track_id.to_base62());
  44. env_vars.insert("DURATION_MS", duration_ms.to_string());
  45. env_vars.insert("POSITION_MS", position_ms.to_string());
  46. }
  47. PlayerEvent::Paused {
  48. track_id,
  49. duration_ms,
  50. position_ms,
  51. ..
  52. } => {
  53. env_vars.insert("PLAYER_EVENT", "paused".to_string());
  54. env_vars.insert("TRACK_ID", track_id.to_base62());
  55. env_vars.insert("DURATION_MS", duration_ms.to_string());
  56. env_vars.insert("POSITION_MS", position_ms.to_string());
  57. }
  58. PlayerEvent::Preloading { track_id, .. } => {
  59. env_vars.insert("PLAYER_EVENT", "preloading".to_string());
  60. env_vars.insert("TRACK_ID", track_id.to_base62());
  61. }
  62. PlayerEvent::VolumeSet { volume } => {
  63. env_vars.insert("PLAYER_EVENT", "volume_set".to_string());
  64. env_vars.insert("VOLUME", volume.to_string());
  65. }
  66. _ => return None,
  67. }
  68. Some(run_program(onevent, env_vars))
  69. }
  70. pub fn emit_sink_event(sink_status: SinkStatus, onevent: &str) {
  71. let mut env_vars = HashMap::new();
  72. env_vars.insert("PLAYER_EVENT", "sink".to_string());
  73. let sink_status = match sink_status {
  74. SinkStatus::Running => "running",
  75. SinkStatus::TemporarilyClosed => "temporarily_closed",
  76. SinkStatus::Closed => "closed",
  77. };
  78. env_vars.insert("SINK_STATUS", sink_status.to_string());
  79. let _ = run_program(onevent, env_vars).and_then(|child| child.wait());
  80. }