Advertisement
Guest User

startup

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