Add Info-Beamer deployment package with touch/swipe functionality for Tv-Anunturi player
This commit is contained in:
BIN
Tv-Anunturi-InfoBeamer-Package.zip
Normal file
BIN
Tv-Anunturi-InfoBeamer-Package.zip
Normal file
Binary file not shown.
@@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"server_url": "http://192.168.1.22",
|
"server_url": "http://192.168.1.22",
|
||||||
"player_id": "REPLACE_WITH_YOUR_DEVICE_ID",
|
"player_id": "12131415",
|
||||||
"refresh_interval": 30,
|
"refresh_interval": 30,
|
||||||
"default_duration": 10
|
"default_duration": 10,
|
||||||
|
"touch_enabled": true,
|
||||||
|
"swipe_threshold": 100,
|
||||||
|
"manual_override_duration": 10
|
||||||
}
|
}
|
||||||
|
|||||||
24
deployment-package/README.md
Normal file
24
deployment-package/README.md
Normal file
@@ -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
|
||||||
9
deployment-package/config.json
Normal file
9
deployment-package/config.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
207
deployment-package/node.lua
Normal file
207
deployment-package/node.lua
Normal file
@@ -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()
|
||||||
BIN
deployment-package/roboto.ttf
Normal file
BIN
deployment-package/roboto.ttf
Normal file
Binary file not shown.
122
node.lua
122
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 player_id = CONFIG.player_id or "default_player"
|
||||||
local refresh_interval = CONFIG.refresh_interval or 30
|
local refresh_interval = CONFIG.refresh_interval or 30
|
||||||
local default_duration = CONFIG.default_duration or 10
|
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 playlist = {}
|
||||||
local current_item = 1
|
local current_item = 1
|
||||||
@@ -15,6 +18,15 @@ local item_start_time = 0
|
|||||||
local last_update = 0
|
local last_update = 0
|
||||||
local channel_info = {}
|
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()
|
function update_playlist()
|
||||||
-- Fetch channel content from server
|
-- Fetch channel content from server
|
||||||
local url = server_url .. "/api/player/" .. player_id .. "/content"
|
local url = server_url .. "/api/player/" .. player_id .. "/content"
|
||||||
@@ -48,17 +60,94 @@ function update_playlist()
|
|||||||
last_update = sys.now()
|
last_update = sys.now()
|
||||||
end
|
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()
|
function node.render()
|
||||||
-- Update playlist periodically
|
-- Update playlist periodically
|
||||||
if sys.now() - last_update > refresh_interval then
|
if sys.now() - last_update > refresh_interval then
|
||||||
update_playlist()
|
update_playlist()
|
||||||
end
|
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 no playlist items, show waiting message
|
||||||
if #playlist == 0 then
|
if #playlist == 0 then
|
||||||
font:write(100, 100, "Waiting for channel content...", 50, 1, 1, 1, 1)
|
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, 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, 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
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -71,14 +160,9 @@ function node.render()
|
|||||||
|
|
||||||
local duration = item.duration or default_duration
|
local duration = item.duration or default_duration
|
||||||
|
|
||||||
-- Check if it's time to move to next item
|
-- Only advance automatically if not in manual override mode
|
||||||
if sys.now() - item_start_time > duration then
|
if not manual_override and sys.now() - item_start_time > duration then
|
||||||
current_item = current_item + 1
|
next_content()
|
||||||
if current_item > #playlist then
|
|
||||||
current_item = 1
|
|
||||||
end
|
|
||||||
item_start_time = sys.now()
|
|
||||||
item = playlist[current_item]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Display current item
|
-- Display current item
|
||||||
@@ -89,13 +173,29 @@ function node.render()
|
|||||||
item.resource:draw(0, 0, WIDTH, HEIGHT)
|
item.resource:draw(0, 0, WIDTH, HEIGHT)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Show channel info overlay (optional)
|
-- Show channel info overlay
|
||||||
if channel_info.name then
|
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
|
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
|
||||||
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
|
end
|
||||||
|
|
||||||
-- Show current time
|
-- Show current time
|
||||||
|
|||||||
Reference in New Issue
Block a user