Files
beamer/node.lua

208 lines
7.2 KiB
Lua

-- Info-Beamer script with streaming channel support
gl.setup(NATIVE_WIDTH, NATIVE_HEIGHT)
local json = require "json"
local font = resource.load_font "roboto.ttf"
local server_url = CONFIG.server_url or "http://192.168.1.22"
local player_id = CONFIG.player_id or "default_player"
local refresh_interval = CONFIG.refresh_interval or 30
local default_duration = CONFIG.default_duration or 10
local touch_enabled = CONFIG.touch_enabled ~= false -- Default to true
local swipe_threshold = CONFIG.swipe_threshold or 100
local manual_override_duration = CONFIG.manual_override_duration or 10
local playlist = {}
local current_item = 1
local item_start_time = 0
local last_update = 0
local channel_info = {}
-- Touch and swipe variables
local touch_start_x = 0
local touch_start_y = 0
local touch_start_time = 0
local is_touching = false
local swipe_time_limit = 1.0 -- Maximum time for swipe (seconds)
local manual_override = false
local manual_override_time = 0
function update_playlist()
-- Fetch channel content from server
local url = server_url .. "/api/player/" .. player_id .. "/content"
util.post_and_wait(url, "", function(response)
if response.success then
local data = json.decode(response.content)
if data and data.content then
playlist = data.content
print("Updated channel content: " .. #playlist .. " items")
-- Load assets
for i, item in ipairs(playlist) do
if item.type == "image" then
item.resource = resource.load_image(server_url .. "/uploads/" .. item.filename)
elseif item.type == "video" then
item.resource = resource.load_video(server_url .. "/uploads/" .. item.filename)
end
end
end
end
end)
-- Also fetch channel information
local channel_url = server_url .. "/api/player/" .. player_id .. "/channel"
util.post_and_wait(channel_url, "", function(response)
if response.success then
channel_info = json.decode(response.content) or {}
end
end)
last_update = sys.now()
end
-- Touch event handlers
function node.on_touch(touches)
for touch in touches() do
if touch.type == "start" then
-- Touch started
touch_start_x = touch.x
touch_start_y = touch.y
touch_start_time = sys.now()
is_touching = true
elseif touch.type == "end" and is_touching then
-- Touch ended - check for swipe
local touch_end_x = touch.x
local touch_end_y = touch.y
local touch_duration = sys.now() - touch_start_time
-- Calculate swipe distance and direction
local dx = touch_end_x - touch_start_x
local dy = touch_end_y - touch_start_y
local distance = math.sqrt(dx * dx + dy * dy)
-- Check if it's a valid swipe (horizontal, sufficient distance, quick enough)
if distance > swipe_threshold and
touch_duration < swipe_time_limit and
math.abs(dx) > math.abs(dy) * 2 then -- More horizontal than vertical
if #playlist > 1 then -- Only allow swipe if there's content to switch to
if dx > 0 then
-- Swipe right - next item
next_content()
else
-- Swipe left - previous item
previous_content()
end
-- Enable manual override mode
manual_override = true
manual_override_time = sys.now()
print("Swipe detected: " .. (dx > 0 and "right (next)" or "left (previous)"))
end
end
is_touching = false
end
end
end
-- Function to go to next content item
function next_content()
if #playlist > 0 then
current_item = current_item + 1
if current_item > #playlist then
current_item = 1
end
item_start_time = sys.now()
end
end
-- Function to go to previous content item
function previous_content()
if #playlist > 0 then
current_item = current_item - 1
if current_item < 1 then
current_item = #playlist
end
item_start_time = sys.now()
end
end
function node.render()
-- Update playlist periodically
if sys.now() - last_update > refresh_interval then
update_playlist()
end
-- Check if manual override has expired
if manual_override and sys.now() - manual_override_time > manual_override_duration then
manual_override = false
item_start_time = sys.now() -- Reset automatic timing
end
-- If no playlist items, show waiting message
if #playlist == 0 then
font:write(100, 100, "Waiting for channel content...", 50, 1, 1, 1, 1)
font:write(100, 200, "Server: " .. server_url, 30, 0.7, 0.7, 0.7, 1)
font:write(100, 250, "Player ID: " .. player_id, 30, 0.7, 0.7, 0.7, 1)
font:write(100, 300, "Swipe left/right to navigate when content is available", 20, 0.5, 0.5, 0.5, 1)
return
end
local item = playlist[current_item]
if not item then
current_item = 1
item = playlist[current_item]
if not item then return end
end
local duration = item.duration or default_duration
-- Only advance automatically if not in manual override mode
if not manual_override and sys.now() - item_start_time > duration then
next_content()
end
-- Display current item
if item and item.resource then
if item.type == "image" then
item.resource:draw(0, 0, WIDTH, HEIGHT)
elseif item.type == "video" then
item.resource:draw(0, 0, WIDTH, HEIGHT)
end
-- Show channel info overlay
if channel_info.name then
font:write(10, HEIGHT - 80, "Channel: " .. channel_info.name, 20, 1, 1, 1, 0.8)
if channel_info.description then
font:write(10, HEIGHT - 50, channel_info.description, 18, 1, 1, 1, 0.7)
end
end
-- Show content navigation info
if #playlist > 1 then
local nav_text = string.format("%d / %d", current_item, #playlist)
font:write(10, HEIGHT - 20, nav_text, 16, 1, 1, 1, 0.6)
-- Show swipe instructions (fade in/out)
local instructions_alpha = 0.4 + 0.2 * math.sin(sys.now() * 2)
font:write(10, 30, "◀ Swipe to navigate ▶", 18, 1, 1, 1, instructions_alpha)
end
-- Show manual override indicator
if manual_override then
local remaining = manual_override_duration - (sys.now() - manual_override_time)
font:write(WIDTH - 150, HEIGHT - 20, string.format("Manual: %.1fs", remaining), 16, 1, 1, 0, 0.8)
end
end
-- Show current time
local current_time = os.date("%H:%M")
font:write(WIDTH - 100, 20, current_time, 24, 1, 1, 1, 0.9)
end
-- Initial load
update_playlist()