subread/player_state.lua (1635 bytes)
1 --[[-- 2 State line of the audio player, as SubRead Overlay reports it. 3 4 Pure Lua. No KOReader dependency, so it can be unit tested on a PC. 5 6 SubRead Overlay is an Android app with notification access. It reads the 7 media session of the player and gives one line to other apps: 8 9 playing=1;position=96153;speed=1.0;package=de.ph1b.audiobook 10 11 The position is in milliseconds, for the moment of the query. A problem is 12 one line `error=<reason>`. 13 --]]-- 14 15 local PlayerState = {} 16 17 --- Parses a state line. 18 -- @return a table { playing, position (seconds), speed, package }, or nil 19 -- and an error name. A report without a position has position nil. 20 function PlayerState.parse(line) 21 if type(line) ~= "string" or line == "" then return nil, "empty" end 22 local fields = {} 23 for key, value in line:gmatch("([%w_]+)=([^;]*)") do 24 fields[key] = value 25 end 26 if fields.error then return nil, fields.error end 27 if not fields.playing or not fields.position then return nil, "malformed" end 28 local position_ms = tonumber(fields.position) 29 if not position_ms then return nil, "malformed" end 30 local speed = tonumber(fields.speed) or 1.0 31 if speed <= 0 then speed = 1.0 end 32 return { 33 playing = fields.playing == "1", 34 position = position_ms >= 0 and position_ms / 1000 or nil, 35 speed = speed, 36 package = fields.package, 37 } 38 end 39 40 --- Converts a position in seconds to the milliseconds string of a seek call. 41 function PlayerState.seekArgument(seconds) 42 if seconds < 0 then seconds = 0 end 43 return string.format("%d", math.floor(seconds * 1000 + 0.5)) 44 end 45 46 return PlayerState