diff --git a/Tv-Anunturi-InfoBeamer-Package.zip b/Tv-Anunturi-InfoBeamer-Package.zip new file mode 100644 index 0000000..77b760a Binary files /dev/null and b/Tv-Anunturi-InfoBeamer-Package.zip differ diff --git a/config.json b/config.json index 587319c..d4c9712 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,9 @@ { "server_url": "http://192.168.1.22", - "player_id": "REPLACE_WITH_YOUR_DEVICE_ID", + "player_id": "12131415", "refresh_interval": 30, - "default_duration": 10 + "default_duration": 10, + "touch_enabled": true, + "swipe_threshold": 100, + "manual_override_duration": 10 } diff --git a/deployment-package/README.md b/deployment-package/README.md new file mode 100644 index 0000000..de74471 --- /dev/null +++ b/deployment-package/README.md @@ -0,0 +1,24 @@ +# Info-Beamer Package for Tv-Anunturi (ID: 12131415) + +## Files: +- node.lua (main script) +- config.json (configured for your player) +- roboto.ttf (font file) + +## Deployment: +1. Upload all 3 files to Info-Beamer +2. Assign package to device ID: 12131415 +3. Device will auto-connect to server at 192.168.1.22 + +## Features: +- Touch screen swipe navigation (left/right) +- Automatic content updates every 30 seconds +- Shows content from Default Channel +- Manual override with touch control + +## Touch Usage: +- Swipe right = next content +- Swipe left = previous content +- Auto-resume after 10 seconds + +Server: http://192.168.1.22/admin diff --git a/deployment-package/config.json b/deployment-package/config.json new file mode 100644 index 0000000..d4c9712 --- /dev/null +++ b/deployment-package/config.json @@ -0,0 +1,9 @@ +{ + "server_url": "http://192.168.1.22", + "player_id": "12131415", + "refresh_interval": 30, + "default_duration": 10, + "touch_enabled": true, + "swipe_threshold": 100, + "manual_override_duration": 10 +} diff --git a/deployment-package/node.lua b/deployment-package/node.lua new file mode 100644 index 0000000..498fe3d --- /dev/null +++ b/deployment-package/node.lua @@ -0,0 +1,207 @@ +-- 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() diff --git a/deployment-package/roboto.ttf b/deployment-package/roboto.ttf new file mode 100644 index 0000000..9f9f520 Binary files /dev/null and b/deployment-package/roboto.ttf differ diff --git a/node.lua b/node.lua index ed8257b..498fe3d 100644 --- a/node.lua +++ b/node.lua @@ -8,6 +8,9 @@ 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 @@ -15,6 +18,15 @@ 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" @@ -48,17 +60,94 @@ function update_playlist() 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 @@ -71,14 +160,9 @@ function node.render() local duration = item.duration or default_duration - -- Check if it's time to move to next item - if sys.now() - item_start_time > duration then - current_item = current_item + 1 - if current_item > #playlist then - current_item = 1 - end - item_start_time = sys.now() - item = playlist[current_item] + -- 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 @@ -89,13 +173,29 @@ function node.render() item.resource:draw(0, 0, WIDTH, HEIGHT) end - -- Show channel info overlay (optional) + -- Show channel info overlay if channel_info.name then - font:write(10, HEIGHT - 60, "Channel: " .. channel_info.name, 20, 1, 1, 1, 0.8) + font:write(10, HEIGHT - 80, "Channel: " .. channel_info.name, 20, 1, 1, 1, 0.8) if channel_info.description then - font:write(10, HEIGHT - 30, channel_info.description, 20, 1, 1, 1, 0.8) + 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