Guest User

startup

a guest
Aug 9th, 2024
350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 19.01 KB | None | 0 0
  1. local api_base_url = "https://ipod-2to6magyna-uc.a.run.app/"
  2.  
  3. local width, height = term.getSize()
  4.  
  5. local tab = 1
  6. local waiting_for_input = false
  7. local last_search = nil
  8. local last_search_url = nil
  9. local search_results = nil
  10. local search_error = false
  11. local in_fullscreen = 0
  12. local clicked_result = nil
  13.  
  14. local playing = false
  15. local queue = {}
  16. local now_playing = nil
  17. local looping = false
  18.  
  19. local playing_id = nil
  20. local last_download_url = nil
  21. local playing_status = 0
  22.  
  23. local player_handle = nil
  24. local start = nil
  25. local pcm = nil
  26. local size = nil
  27. local decoder = nil
  28. local needs_next_chunk = 0
  29. local buffer
  30.  
  31.  
  32. local speakers = { peripheral.find("speaker") }
  33. local speakerStatus ={}
  34.  
  35. for i = 1, #speakers do
  36. speakerStatus[i] = {playing = false, needsSync = false}
  37. end
  38.  
  39.  
  40.  
  41. local function playAudioOnSpeakers(buffer)
  42.  
  43. local allPlaying = true
  44.  
  45.  
  46. for i, speaker in ipairs(speakers) do
  47. if speakerStatus[i].needsSync then
  48. allPlaying = false
  49. break
  50. end
  51. end
  52. if allPlaying then
  53.  
  54. for i,speaker in ipairs(speakers) do
  55. while not speaker.playAudio(buffer) do
  56. sleep(5.50)
  57. end
  58.  
  59. speakerStatus[1].playing = true
  60. end
  61. end
  62. end
  63.  
  64.  local function monitorSpeakers()
  65.  while true do
  66.  local allFinished = true
  67.  
  68.  for i, speaker in ipairs(speakers) do
  69.  if speakerStatus[i].playing then
  70.  allFinished = false
  71.  break
  72.  end
  73.  end
  74.  
  75.  if allFinished then
  76.  for i = 1, #speakers do
  77.   speakerStatus[i].playing = false
  78.   speakerStatus[i].needsSync = false
  79.   end
  80.   needs_next_chunk = 3 -- Allow next chunk to be played
  81.   else
  82.   for i, speaker in ipairs(speakers) do
  83.   if speakerStatus[i].playing then
  84.   speaker.stop()
  85.   speakerStatus[i].needsSync = true
  86.  end
  87.  end
  88.  end
  89.  sleep(5.5)
  90.  end
  91.  end
  92.  
  93.  
  94. local function redrawScreen()
  95.     if waiting_for_input == true then
  96.         return
  97.     end
  98.  
  99.     -- DRAWING
  100.     term.setBackgroundColor(colors.black)
  101.     term.clear()
  102.  
  103.     --tabs
  104.     term.setCursorPos(1,1)
  105.     term.setBackgroundColor(colors.gray)
  106.     term.clearLine()
  107.  
  108.     tabs = {" Now Playing ", " Search "}
  109.  
  110.     for i=1,2,1 do
  111.         if tab == i then
  112.             term.setTextColor(colors.black)
  113.             term.setBackgroundColor(colors.white)
  114.         else
  115.             term.setTextColor(colors.white)
  116.             term.setBackgroundColor(colors.gray)
  117.         end
  118.  
  119.         term.setCursorPos((math.floor((width/2)*(i-0.5)))-math.ceil(#tabs[i]/2)+1, 1)
  120.         term.write(tabs[i])
  121.     end
  122.  
  123.     --now playing tab
  124.     if tab == 1 then
  125.         if now_playing ~= nil then
  126.             term.setBackgroundColor(colors.black)
  127.             term.setTextColor(colors.white)
  128.             term.setCursorPos(2,3)
  129.             term.write(now_playing.name)
  130.             term.setTextColor(colors.lightGray)
  131.             term.setCursorPos(2,4)
  132.             term.write(now_playing.artist)
  133.         else
  134.             term.setBackgroundColor(colors.black)
  135.             term.setTextColor(colors.lightGray)
  136.             term.setCursorPos(2,3)
  137.             term.write("Not playing")
  138.         end
  139.  
  140.         term.setTextColor(colors.white)
  141.         term.setBackgroundColor(colors.gray)
  142.  
  143.         if playing then
  144.             term.setCursorPos(2, 6)
  145.             term.write(" Stop ")
  146.         else
  147.             if now_playing ~= nil or #queue > 0 then
  148.                 term.setTextColor(colors.white)
  149.                 term.setBackgroundColor(colors.gray)
  150.             else
  151.                 term.setTextColor(colors.lightGray)
  152.                 term.setBackgroundColor(colors.gray)
  153.             end
  154.             term.setCursorPos(2, 6)
  155.             term.write(" Play ")
  156.         end
  157.  
  158.         if now_playing ~= nil or #queue > 0 then
  159.             term.setTextColor(colors.white)
  160.             term.setBackgroundColor(colors.gray)
  161.         else
  162.             term.setTextColor(colors.lightGray)
  163.             term.setBackgroundColor(colors.gray)
  164.         end
  165.         term.setCursorPos(2 + 8, 6)
  166.         term.write(" Skip ")
  167.  
  168.         if looping then
  169.             term.setTextColor(colors.black)
  170.             term.setBackgroundColor(colors.white)
  171.         else
  172.             term.setTextColor(colors.white)
  173.             term.setBackgroundColor(colors.gray)
  174.         end
  175.         term.setCursorPos(2 + 8 + 8, 6)
  176.         term.write(" Loop ")
  177.  
  178.         --search results
  179.         if #queue > 0 then
  180.             term.setBackgroundColor(colors.black)
  181.             for i=1,#queue do
  182.                 term.setTextColor(colors.white)
  183.                 term.setCursorPos(2,8 + (i-1)*2)
  184.                 term.write(queue[i].name)
  185.                 term.setTextColor(colors.lightGray)
  186.                 term.setCursorPos(2,9 + (i-1)*2)
  187.                 term.write(queue[i].artist)
  188.             end
  189.         end
  190.     end
  191.  
  192.     --search tab
  193.     if tab == 2 then
  194.  
  195.         -- search bar
  196.         for a=3,5,1 do
  197.             term.setCursorPos(2,a)
  198.             term.setTextColor(colors.lightGray)
  199.             term.setBackgroundColor(colors.lightGray)
  200.             for i=1,width-2,1 do
  201.                 term.write(" ")
  202.             end
  203.         end
  204.         term.setCursorPos(3,4)
  205.         term.setTextColor(colors.black)
  206.         term.write(last_search or "Search...")
  207.  
  208.         --search results
  209.         if search_results ~= nil then
  210.             term.setBackgroundColor(colors.black)
  211.             for i=1,#search_results do
  212.                 term.setTextColor(colors.white)
  213.                 term.setCursorPos(2,7 + (i-1)*2)
  214.                 term.write(search_results[i].name)
  215.                 term.setTextColor(colors.lightGray)
  216.                 term.setCursorPos(2,8 + (i-1)*2)
  217.                 term.write(search_results[i].artist)
  218.             end
  219.         else
  220.             term.setCursorPos(2,7)
  221.             term.setBackgroundColor(colors.black)
  222.             if search_error == true then
  223.                 term.setTextColor(colors.red)
  224.                 term.write("Error")
  225.             else
  226.                 if last_search_url ~= nil then
  227.                     term.setTextColor(colors.white)
  228.                     term.write("Searching...")
  229.                 else
  230.  
  231.                 end
  232.             end
  233.         end
  234.  
  235.         --fullscreen song options
  236.         if in_fullscreen == 1 then
  237.             term.setBackgroundColor(colors.black)
  238.             term.clear()
  239.             term.setCursorPos(2,2)
  240.             term.setTextColor(colors.white)
  241.             term.write(search_results[clicked_result].name)
  242.             term.setCursorPos(2,3)
  243.             term.setTextColor(colors.lightGray)
  244.             term.write(search_results[clicked_result].artist)
  245.  
  246.             term.setBackgroundColor(colors.gray)
  247.             term.setTextColor(colors.white)
  248.  
  249.             term.setCursorPos(2,6)
  250.             term.clearLine()
  251.             term.write("Play now")
  252.  
  253.             term.setCursorPos(2,8)
  254.             term.clearLine()
  255.             term.write("Play next")
  256.  
  257.             term.setCursorPos(2,10)
  258.             term.clearLine()
  259.             term.write("Add to queue")
  260.  
  261.             term.setCursorPos(2,13)
  262.             term.clearLine()
  263.             term.write("Cancel")
  264.         end
  265.  
  266.     end
  267. end
  268.  
  269. local function searchInput()
  270.     while true do
  271.         if waiting_for_input == true then
  272.             for a=3,5,1 do
  273.                 term.setCursorPos(2,a)
  274.                 term.setTextColor(colors.white)
  275.                 term.setBackgroundColor(colors.white)
  276.                 for i=1,width-2,1 do
  277.                     term.write(" ")
  278.                 end
  279.             end
  280.             term.setCursorPos(3,4)
  281.             term.setTextColor(colors.black)
  282.             local input = read()
  283.             if string.len(input) > 0 then
  284.                 last_search = input
  285.                 last_search_url = api_base_url .. "?search=" .. textutils.urlEncode(input)
  286.                 http.request(last_search_url)
  287.                 search_results = nil
  288.                 search_error = false
  289.             else
  290.                 last_search = nil
  291.                 last_search_url = nil
  292.                 search_results = nil
  293.                 search_error = false
  294.             end
  295.  
  296.             waiting_for_input = false
  297.  
  298.             redrawScreen()
  299.         end
  300.  
  301.         sleep(0.1)
  302.     end
  303. end
  304.  
  305. local function mainLoop()
  306.     redrawScreen()
  307.  
  308.     while true do
  309.  
  310.         -- AUDIO
  311.         if playing and now_playing then
  312.             if playing_id ~= now_playing.id then
  313.                 playing_id = now_playing.id
  314.                 last_download_url = api_base_url .. "?id=" .. textutils.urlEncode(playing_id)
  315.                 playing_status = 0
  316.                 needs_next_chunk = 1
  317.  
  318.                 http.request({url = last_download_url, binary = true})
  319.  
  320.                 redrawScreen()
  321.             end
  322.             if playing_status == 1 and needs_next_chunk == 3 then
  323.                 needs_next_chunk = 1
  324.  
  325.                 while not playAudioOnSpeakers(buffer) do
  326.                     needs_next_chunk = 2
  327.                     break
  328.                 end
  329.             end
  330.             if playing_status == 1 and needs_next_chunk == 1 then
  331.  
  332.                 while true do
  333.                     local chunk = player_handle.read(size)
  334.                     if not chunk then
  335.                         if looping then
  336.                             playing_id = nil
  337.                         else
  338.                             if #queue > 0 then
  339.                                 now_playing = queue[1]
  340.                                 table.remove(queue, 1)
  341.                                 playing_id = nil
  342.                             else
  343.                                 now_playing = nil
  344.                                 playing = false
  345.                                 playing_id = nil
  346.                             end
  347.                         end
  348.  
  349.                         redrawScreen()
  350.  
  351.                         player_handle.close()
  352.                         needs_next_chunk = 0
  353.                         break
  354.                     else
  355.                         if start then
  356.                             chunk, start = start .. chunk, nil
  357.                             size = size + 4
  358.                         end
  359.  
  360.                         buffer = decoder(chunk)
  361.                          playAudioOnSpeakers(buffer)
  362.                             if needs_next_chunk == 2 then
  363.                             break
  364.                         end
  365.                     end
  366.                 end
  367.  
  368.             end
  369.         end
  370.  
  371.         -- EVENTS
  372.         local event, param1, param2, param3 = os.pullEvent()    
  373.  
  374.         -- CLICK EVENTS
  375.         if event == "mouse_click" and waiting_for_input == false then
  376.  
  377.             local button = param1
  378.             local x = param2
  379.             local y = param3
  380.  
  381.             -- tabs
  382.             if button == 1 and in_fullscreen == 0 then
  383.                 if y == 1 then
  384.                     if x < width/2 then
  385.                         tab = 1
  386.                     else
  387.                         tab = 2
  388.                     end
  389.                 end
  390.             end
  391.  
  392.             --fullscreen windows
  393.             if in_fullscreen == 1 then
  394.                 term.setBackgroundColor(colors.white)
  395.                 term.setTextColor(colors.black)
  396.  
  397.                 if y == 6 then
  398.                     term.setCursorPos(2,6)
  399.                     term.clearLine()
  400.                     term.write("Play now")
  401.                     sleep(0.2)
  402.                     in_fullscreen = 0
  403.                     now_playing = search_results[clicked_result]
  404.                     playing = true
  405.                     playing_id = nil
  406.                 end
  407.  
  408.                 if y == 8 then
  409.                     term.setCursorPos(2,8)
  410.                     term.clearLine()
  411.                     term.write("Play next")
  412.                     sleep(0.2)
  413.                     in_fullscreen = 0
  414.                     table.insert(queue, 1, search_results[clicked_result])
  415.                 end
  416.  
  417.                 if y == 10 then
  418.                     term.setCursorPos(2,10)
  419.                     term.clearLine()
  420.                     term.write("Add to queue")
  421.                     sleep(0.2)
  422.                     in_fullscreen = 0
  423.                     table.insert(queue, search_results[clicked_result])
  424.                 end
  425.  
  426.                 if y == 13 then
  427.                     term.setCursorPos(2,13)
  428.                     term.clearLine()
  429.                     term.write("Cancel")
  430.                     sleep(0.2)
  431.                     in_fullscreen = 0
  432.                 end
  433.             else
  434.  
  435.                 -- now playing tab
  436.                 if tab == 1 and button == 1 then
  437.                     if y == 6 then
  438.                         if x >= 2 and x <= 2 + 6 then
  439.                             local animate = false
  440.                             local was_playing = playing
  441.                             if playing then
  442.                                 playing = false
  443.                                 animate = true
  444.                                 for _, speakers in ipairs(speakers) do
  445.                                 speakers.stop()
  446.                                 end
  447.                                 playing_id = nil
  448.                             else
  449.                                 if now_playing ~= nil then
  450.                                     playing_id = nil
  451.                                     playing = true
  452.                                     animate = true
  453.                                 else
  454.                                     if #queue > 0 then
  455.                                         now_playing = queue[1]
  456.                                         table.remove(queue, 1)
  457.                                         playing_id = nil
  458.                                         playing = true
  459.                                         animate = true
  460.                                     end
  461.                                 end
  462.                             end
  463.                             if animate == true then
  464.                                 term.setBackgroundColor(colors.white)
  465.                                 term.setTextColor(colors.black)
  466.                                 term.setCursorPos(2, 6)
  467.                                 if was_playing then
  468.                                     term.write(" Stop ")
  469.                                 else
  470.                                     term.write(" Play ")
  471.                                 end
  472.                                 sleep(0.2)
  473.                             end
  474.                         end
  475.                         if x >= 2 + 8 and x <= 2 + 8 + 6 then
  476.                             local animate = false
  477.                             if playing then
  478.                                 for _, speakers in ipairs(speakers) do
  479.                                 speakers.stop()
  480.                                 end
  481.                             end
  482.                             if now_playing ~= nil or #queue > 0 then
  483.                                 if #queue > 0 then
  484.                                     now_playing = queue[1]
  485.                                     table.remove(queue, 1)
  486.                                     playing_id = nil
  487.                                 else
  488.                                     now_playing = nil
  489.                                     playing = false
  490.                                     playing_id = nil
  491.                                 end
  492.                                 animate = true
  493.                             end
  494.                             if animate == true then
  495.                                 term.setBackgroundColor(colors.white)
  496.                                 term.setTextColor(colors.black)
  497.                                 term.setCursorPos(2 + 8, 6)
  498.                                 term.write(" Skip ")
  499.                                 sleep(0.2)
  500.                             end
  501.                         end
  502.                         if x >= 2 + 8 + 8 and x <= 2 + 8 + 8 + 6 then
  503.                             if looping then
  504.                                 looping = false
  505.                             else
  506.                                 looping = true
  507.                             end
  508.                         end
  509.                     end
  510.                 end
  511.  
  512.                 -- search tab clicks
  513.                 if tab == 2 and button == 1 then
  514.                     -- search box click
  515.                     if y >= 3 and y <= 5 and x >= 1 and x <= width-1 then
  516.                         waiting_for_input = true
  517.                     end
  518.  
  519.                     -- search result click
  520.                     if search_results then
  521.                         for i=1,#search_results do
  522.                             if y == 7 + (i-1)*2 or y == 8 + (i-1)*2 then
  523.                                 term.setBackgroundColor(colors.white)
  524.                                 term.setTextColor(colors.black)
  525.                                 term.setCursorPos(2,7 + (i-1)*2)
  526.                                 term.clearLine()
  527.                                 term.write(search_results[i].name)
  528.                                 term.setTextColor(colors.gray)
  529.                                 term.setCursorPos(2,8 + (i-1)*2)
  530.                                 term.clearLine()
  531.                                 term.write(search_results[i].artist)
  532.                                 sleep(0.2)
  533.                                 in_fullscreen = 1
  534.                                 clicked_result = i
  535.                             end
  536.                         end
  537.                     end
  538.                 end
  539.             end
  540.  
  541.             redrawScreen()
  542.  
  543.         end
  544.  
  545.         -- HTTP EVENTS
  546.         if event == "http_success" then
  547.             local url = param1
  548.             local handle = param2
  549.  
  550.             if url == last_search_url then
  551.                 search_results = textutils.unserialiseJSON(handle.readAll())
  552.                 redrawScreen()
  553.             end
  554.             if url == last_download_url then
  555.                 player_handle = handle
  556.                 start = handle.read(4)
  557.                 size = 16 * 1024 - 4
  558.                 if start == "RIFF" then
  559.                     error("WAV not supported!")
  560.                 end
  561.                 playing_status = 1
  562.                 decoder = require "cc.audio.dfpwm".make_decoder()
  563.             end
  564.         end
  565.  
  566.         if event == "http_failure" then
  567.             local url = param1
  568.  
  569.             if url == last_search_url then
  570.                 search_error = true
  571.                 redrawScreen()
  572.             end
  573.             if url == last_download_url then
  574.                 if #queue > 0 then
  575.                     now_playing = queue[1]
  576.                     table.remove(queue, 1)
  577.                     playing_id = nil
  578.                 else
  579.                     now_playing = nil
  580.                     playing = false
  581.                     playing_id = nil
  582.                 end
  583.                 redrawScreen()
  584.             end
  585.         end
  586.  
  587.         if event == "timer" then
  588.             os.startTimer(1)
  589.         end
  590.  
  591.         if event == "speakers_audio_empty" then
  592.             for _, speaker in ipairs(speakers) do
  593.             if needs_next_chunk == 2 then
  594.                 needs_next_chunk = 3
  595.             end
  596.         end
  597.     end
  598.     end
  599.  
  600.     sleep(0.1)
  601. end
  602.  
  603. parallel.waitForAny(mainLoop, searchInput)
  604.  
Advertisement
Add Comment
Please, Sign In to add comment