Class: EdlParser
- Inherits:
-
Object
- Object
- EdlParser
- Defined in:
- lib/edl_parser.rb
Constant Summary collapse
- EDL_DIR =
File.(__DIR__ + "/../zamples/edit_decision_lists/dvds")
Class Method Summary collapse
- .all_edl_files_parsed(use_all_not_just_dvds) ⇒ Object
-
.convert_incoming_to_split_sectors(incoming, add_this_to_all_ends = 0, subtract_this_from_beginnings = 0, splits = [], subtract_this_from_ends = 0) ⇒ Object
called later, from external files divides up mutes and blanks so that they don’t overlap, preferring blanks over mutes returns it like [[start,end,type], [s,e,t]…] type like either :blank and :mute [ [70.0, 73.0, :blank], [378.0, 379.1, :mute], … ].
- .convert_to_dvd_nav_times(combined, start_type, start_mpeg_time, dvd_nav_packet_offsets, time_multiplier) ⇒ Object
-
.find_single_edit_list_matching(use_all_not_just_dvd_dir = false, return_first_if_there_are_several = false) ⇒ Object
returns single matching filename requires a block.
- .on_any_file_changed_single_cached_thread(&this_block) ⇒ Object
-
.parse_file(filename, expand = true) ⇒ Object
returns => [[“00:00”, “00:00”, string1, string2, …], …], “blank_outs” -> […], “url” => ….
- .parse_imdb(output, imdb_id) ⇒ Object
- .single_edit_list_matches_dvd(dvd_id, return_first_if_there_are_several = false) ⇒ Object
-
.translate_string_to_seconds(s) ⇒ Object
this one is 1:01:02.0 => 36692.0 its reverse is this: translate_time_to_human_readable.
-
.translate_time_to_human_readable(seconds, force_hour_stamp = false) ⇒ Object
its reverse: translate_string_to_seconds.
Class Method Details
.all_edl_files_parsed(use_all_not_just_dvds) ⇒ Object
301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/edl_parser.rb', line 301 def self.all_edl_files_parsed use_all_not_just_dvds dir = EDL_DIR dir += "/.." if use_all_not_just_dvds Dir[dir + '/**/*.txt'].map{|filename| begin parsed = parse_file(filename) [filename, parsed] rescue SyntaxError => e # ignore poorly formed edit lists for the auto choose phase... puts 'warning, unable to parse a file:' + filename + " " + e.to_s nil end }.compact end |
.convert_incoming_to_split_sectors(incoming, add_this_to_all_ends = 0, subtract_this_from_beginnings = 0, splits = [], subtract_this_from_ends = 0) ⇒ Object
called later, from external files divides up mutes and blanks so that they don’t overlap, preferring blanks over mutes returns it like [[start,end,type], [s,e,t]…] type like either :blank and :mute
- [70.0, 73.0, :blank], [378.0, 379.1, :mute], …
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/edl_parser.rb', line 243 def self.convert_incoming_to_split_sectors incoming, add_this_to_all_ends = 0, subtract_this_from_beginnings = 0, splits = [], subtract_this_from_ends = 0 raise if subtract_this_from_beginnings < 0 raise if add_this_to_all_ends < 0 raise if subtract_this_from_ends < 0 add_this_to_all_ends -= subtract_this_from_ends # now we allow negative :) # raise if splits.size > 0 # just ignore them for now mutes = incoming["mutes"] || {} blanks = incoming["blank_outs"] || {} mutes = mutes.map{|k, v| [k,v,:mute]} blanks = blanks.map{|k, v| [k,v,:blank]} combined = (mutes+blanks).map{|s,e,type| [translate_string_to_seconds(s), translate_string_to_seconds(e), type]}.sort # detect any weirdness... previous = nil combined.map!{ |current| s,e,type = current if e < s || !s || !e || !type p caller raise SyntaxError.new("detected an end before a start or other weirdness: #{s} > #{e}") end if previous ps, previous_end, pt = previous if (s < previous_end) raise SyntaxError.new("detected an overlap current #{s} < #{previous_end} of current: #{current.join(' ')} previous: #{previous.join(' ')}") end end previous = current # do the math later to allow for ones that barely hit into each other 1.0 2.0, 2.0 3.0 [s-subtract_this_from_beginnings, e+add_this_to_all_ends,type] } combined end |
.convert_to_dvd_nav_times(combined, start_type, start_mpeg_time, dvd_nav_packet_offsets, time_multiplier) ⇒ Object
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/edl_parser.rb', line 344 def self.convert_to_dvd_nav_times combined, start_type, start_mpeg_time, dvd_nav_packet_offsets, time_multiplier start_dvdnav_time = dvd_nav_packet_offsets[1] - dvd_nav_packet_offsets[0] raise unless start_type == 'dvd_start_offset' # for now :P out = [] add_this_to_all_of_them = start_dvdnav_time - start_mpeg_time #[[70.0, 73.0, :blank], [378.0, 379.1, :mute]] for start, endy, type in combined if time_multiplier == 30 # ok elsif time_multiplier == 29.97 start = ConvertThirtyFps.from_twenty_nine_nine_seven start endy = ConvertThirtyFps.from_twenty_nine_nine_seven endy else raise time_multiplier end start += start_dvdnav_time endy += start_dvdnav_time out << [start, endy, type] end out end |
.find_single_edit_list_matching(use_all_not_just_dvd_dir = false, return_first_if_there_are_several = false) ⇒ Object
returns single matching filename requires a block
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/edl_parser.rb', line 318 def self.find_single_edit_list_matching use_all_not_just_dvd_dir = false, return_first_if_there_are_several = false matching = all_edl_files_parsed(use_all_not_just_dvd_dir).map{|filename, parsed| yield(parsed) ? filename : nil }.compact if matching.length == 1 file = matching[0] file elsif matching.length > 1 p "found multiple matches for media? #{matching.inspect}" if return_first_if_there_are_several matching[0] else nil end else nil end end |
.on_any_file_changed_single_cached_thread(&this_block) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/edl_parser.rb', line 24 def self.on_any_file_changed_single_cached_thread &this_block raise unless this_block get_files_hash = proc { glob = EDL_DIR + '/../**/*' Dir[glob].map{|f| [f, File.mtime(f)] }.sort } old_value = get_files_hash.call @@checking_thread ||= Thread.new { loop { current_value = get_files_hash.call if current_value != old_value print 'detected some file was changed! Re-parsing to update...' old_value = current_value this_block.call puts 'done.' end sleep 2 # 0.02 for size 70, so...hopefully this is ok... } } end |
.parse_file(filename, expand = true) ⇒ Object
returns => [[“00:00”, “00:00”, string1, string2, …], …], “blank_outs” -> […], “url” => …
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/edl_parser.rb', line 78 def self.parse_file filename, = true output = parse_string File.read(filename), filename, [] # now respect a few options if relative = output["take_from_relative_file"] new_filename = File.dirname(filename) + '/' + relative new_input = parse_file new_filename output.merge! new_input end require_relative 'gui/dependencies' # for download methods... if if output["from_url"] # replacement downloaded = SensibleSwing::MainWindow.download_to_string(output["from_url"]) output = parse_string downloaded # full replacement end if imdb_id = output["imdb_id"] parse_imdb output, imdb_id end end output end |
.parse_imdb(output, imdb_id) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/edl_parser.rb', line 103 def self.parse_imdb output, imdb_id require_relative 'convert_thirty_fps' url = "http://www.imdb.com/title/#{imdb_id}/parentalguide" all = SensibleSwing::MainWindow.download_to_string(url) header, violence_word, violence_section, profanity_word, profanity_section, alcohol_word, alcohol_section, frightening_word, frightening_section = sections = all.split(/<span>(Violence|Profanity|Alcohol|Frightening)/) header = sections.shift all ={} while(!sections.empty?) # my klugey to_hash method word_type = sections.shift settings = sections.shift assert word_type.in? ['Violence', 'Profanity', 'Alcohol', 'Frightening'] all[word_type] = settings end # blank_outs or mutes for each... # TODO make the -> optional = /([\d:]+(?:\.\d+|))\W*->\W*([\d:]+(?:\.\d+|))([^\d\n]+)/ for type, settings in all settings.scan() do |begin_ts, end_ts, description| puts "parsing from wiki imdb entry violence: #{begin_ts} #{end_ts} #{description} #{type}" start_seconds = translate_string_to_seconds begin_ts end_seconds = translate_string_to_seconds end_ts # convert from 30 to 29.97 fps ... we presume ... start_seconds = ConvertThirtyFps.from_twenty_nine_nine_seven start_seconds start_seconds = ("%.02f" % start_seconds).to_f # round start_seconds = translate_time_to_human_readable start_seconds, true end_seconds = ConvertThirtyFps.from_twenty_nine_nine_seven end_seconds end_seconds = ("%.02f" % end_seconds).to_f # round end_seconds = translate_time_to_human_readable end_seconds, true p end_seconds if type == 'Profanity' output['mutes'] << [start_seconds, end_seconds] else output['blank_outs'] << [start_seconds, end_seconds] end end end end |
.single_edit_list_matches_dvd(dvd_id, return_first_if_there_are_several = false) ⇒ Object
337 338 339 340 341 342 |
# File 'lib/edl_parser.rb', line 337 def self.single_edit_list_matches_dvd dvd_id, return_first_if_there_are_several = false return nil unless dvd_id find_single_edit_list_matching(false, return_first_if_there_are_several) {|parsed| parsed["disk_unique_id"] == dvd_id } end |
.translate_string_to_seconds(s) ⇒ Object
this one is 1:01:02.0 => 36692.0 its reverse is this: translate_time_to_human_readable
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/edl_parser.rb', line 49 def self.translate_string_to_seconds s # might actually already be a float, or int, depending on the yaml # int for 8 => 9 and also for 1:09 => 1:10 if s.is_a? Numeric return s.to_f # easy out. end s = s.strip # s is like 1:01:02.0 total = 0.0 seconds = nil seconds = s.split(":")[-1] raise 'does not look like a timestamp? ' + seconds.inspect unless seconds =~ /^\d+(|[,.]\d+)$/ seconds.gsub!(',', '.') total += seconds.to_f minutes = s.split(":")[-2] || "0" total += 60 * minutes.to_i hours = s.split(":")[-3] || "0" total += 60* 60 * hours.to_i total end |
.translate_time_to_human_readable(seconds, force_hour_stamp = false) ⇒ Object
its reverse: translate_string_to_seconds
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/edl_parser.rb', line 278 def self.translate_time_to_human_readable seconds, force_hour_stamp = false # 3600 => "1:00:00" out = '' hours = seconds.to_i / 3600 if hours > 0 || force_hour_stamp out << "%d" % hours out << ":" end seconds = seconds - hours*3600 minutes = seconds.to_i / 60 out << "%02d" % minutes seconds = seconds - minutes * 60 out << ":" # avoid an ugly .0 at the end # if seconds == seconds.to_i # out << "%02d" % seconds # else out << "%05.2f" % seconds # man that printf syntax is tricky... # end end |