Created
December 2, 2018 02:05
-
-
Save rennex/78c06ac782753a54809d61e972004151 to your computer and use it in GitHub Desktop.
Media Player Classic activity logger
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: UTF-8 | |
# ----- Settings: ----- | |
# what machine's MPC is monitored, and on which port | |
MPC_HOST = "localhost:13579" | |
LOGFILE = "log.txt" | |
PRINTLOG = false # also print to console? | |
ENDTOLERANCE = 0.95 # seen 95% = seen all of it | |
INTERVAL = 5 # seconds to wait after each status update | |
OUTPUT_CHARSET = "CP850" # this is a fix for windows's cmd.exe | |
LOG_TIME_FORMAT = "%d.%m.%Y %H:%M:%S" | |
# --------------------- | |
# todo: "undefined method `strip' for 720:Fixnum" seen sometimes | |
require "open-uri" | |
# require "json" | |
MPCStatus = Struct.new(:filename, :status, :pos, :posstr, :dur, :durstr, :muted, :volume, :seen_upto) | |
class MPCMonitor | |
def initialize(host) | |
@host = host | |
@prev = emptystatus | |
end | |
def getstatus | |
begin | |
# fetch the status data by http | |
str = open("http://#@host/status.html").read.force_encoding("UTF-8") | |
if str =~ /^OnStatus\((.+)\)/ | |
status = $1 | |
args = [] | |
status.scan(/(\d+|"(([^"]|\\")*?)")(, )?/) do | |
args << ($2 || $1.to_i) | |
end | |
#x = $1.tr('"\'', '\'"') | |
#args = JSON.parse "[#{x}]" | |
#p args | |
# get the file name from the window title | |
#args[0].sub!(/( - )?Media Player Classic.*?$/, "") | |
args[0] = args.slice!(-1) | |
args[0] = nil if args[0].strip == "" | |
args[1] = nil if args[1].strip == "" | |
return MPCStatus[*args, 0] | |
else | |
raise "invalid data received (something other than MPC running at #@host)" | |
end | |
rescue OpenURI::HTTPError | |
raise "unable to connect to MPC - #$!" | |
rescue Errno::ECONNREFUSED, EOFError | |
# if it's not running at all (connection refused) | |
# or exited while replying (EOFError) | |
return emptystatus | |
end | |
end | |
def emptystatus | |
MPCStatus[nil, nil, 0, "00:00:00", 0, "00:00:00", 0, 100, 0] | |
end | |
def ms2txt(ms) | |
s = ms/1000 | |
min = s/60 | |
s %= 60 | |
h = min/60 | |
min %= 60 | |
"%02d:%02d:%02d" % [h,min,s] | |
end | |
def run | |
puts "Commencing monitoring. Polling MPC every #{INTERVAL} seconds." | |
#p STDOUT.external_encoding | |
#STDOUT.set_encoding "CP850" | |
#puts "äöå" | |
#puts "äöå".encode("CP850") | |
#puts "äöå".encoding.name | |
#p Encoding.default_external.name | |
#p __ENCODING__ | |
#p STDOUT.external_encoding | |
loop do | |
begin | |
s = getstatus() | |
# different file? | |
if s.filename != @prev.filename | |
if @prev.filename | |
uptotxt = "watched up to #{ms2txt(@prev.seen_upto)}" | |
if @prev.seen_upto.to_f / @prev.dur >= ENDTOLERANCE | |
uptotxt += ") (finished" | |
end | |
log "Closed file (#{uptotxt})" | |
end | |
if s.filename | |
log "Started playing #{s.filename}" | |
# forget the old file at this point | |
@prev = s | |
s.status = "Playing" | |
s.seen_upto = s.pos | |
end | |
end | |
# status changed? | |
# NOTE: keep the "if s.filename" because sometimes it's nil and s.status=="Opening..." | |
if s.filename && s.status != @prev.status | |
log "#{s.status} at #{s.posstr}" | |
end | |
# how much has been viewed? | |
s.seen_upto = [s.pos, @prev.seen_upto].max | |
@prev = s | |
rescue | |
puts $!.inspect, *$@ | |
#puts "mpclog error: #$!" | |
#puts "Backtrace:\n\t#{$!.backtrace.join("\n\t")}" | |
end | |
sleep INTERVAL | |
end | |
end | |
def log(txt) | |
logline = "#{Time.now.strftime(LOG_TIME_FORMAT)} - #{txt}" | |
File.open(LOGFILE, "a") do |f| | |
f.puts logline | |
end | |
puts logline if PRINTLOG | |
end | |
def puts(*args) | |
STDOUT.puts(*(args.map {|a| a.to_s.encode(OUTPUT_CHARSET, invalid: :replace, undef: :replace, replace: "?")})) | |
end | |
end | |
begin | |
mon = MPCMonitor.new(MPC_HOST) | |
mon.run | |
rescue Interrupt | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment