in reply to report generation

Well you know one thing: a stopped time always comes after a start time.

So create a hash, keyed by URL. As you scan each line add an entry to your hash with a key of URL and value of time. When you encounter a stopped line merely subtract the time from the current line from the time stored in the hash with the same key as the url of the current line.

e.g. meta code:

my %seen = (); # keyed by URL, contains times while ( <line> ) { if ( line =~ m/(date)(action)(URL)/ ) { if ( action == "played" ) { seen{URL} = date; } elsif ( action == "stopped" ) { duration = date - seen{URL}; print( "URL: duration" ); } } }

I'll leave it as an exercise for the student to turn this meta-code into real Perl. You'll probably want to introduce more error checking too.