Last active
December 18, 2015 16:19
-
-
Save eagletmt/5810946 to your computer and use it in GitHub Desktop.
SD -> HD または HD -> SD の切り替えがあるときに、HD または SD の先頭オフセットを見つける
This file contains hidden or 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
#!/usr/bin/env ruby | |
# coding: utf-8 | |
require 'open3' | |
require 'tempfile' | |
class Avconv | |
def initialize(path, bin = 'avconv') | |
@path = path | |
@bin = bin | |
@tempfile = Tempfile.new ['sd-hd', '.ts'] | |
end | |
def skip(t) | |
do_skip t | |
out, err, statuses = Open3.capture3 @bin, '-i', @tempfile.path | |
err.lines | |
end | |
def cuttable?(t) | |
do_skip t | |
system @bin, '-loglevel', 'quiet', '-i', @tempfile.path, '-acodec', 'copy', '-vcodec', 'copy', '-f', 'mpegts', '-t', '20', '-y', File::NULL | |
end | |
def do_skip(t) | |
Open3.pipeline ['tail', '-c', "+#{188*t}", @path], ["head", '-c', '18800000', { out: @tempfile.path }] | |
end | |
end | |
def bsearch(lo, hi, left_p, right_p) | |
while lo < hi | |
mid = (lo + hi)/2 | |
p [lo, hi, mid] | |
if left_p.call mid | |
hi = mid | |
elsif right_p.call mid | |
lo = mid+1 | |
else | |
$stderr.puts "Error at mid=#{mid}" | |
lo = mid+1 | |
#raise "Error at mid=#{mid}" | |
end | |
end | |
lo | |
end | |
SD_SIZE = '720x480' | |
HD_SIZE = '1440x1080' | |
MAIN_STREAM = 'mpeg2video' | |
hd_p = lambda do |lines| | |
lines.any? do |line| | |
line.include? MAIN_STREAM and line.include? HD_SIZE | |
end | |
end | |
sd_p = lambda do |lines| | |
lines.any? do |line| | |
line.include? MAIN_STREAM and line.include? SD_SIZE | |
end | |
end | |
path = ARGV[0] or exit 1 | |
avconv = Avconv.new path | |
MAX_PACKETS = 200000 | |
first_lines = avconv.skip 0 | |
last_lines = avconv.skip MAX_PACKETS | |
left_p = nil, right_p = nil | |
if sd_p.call first_lines and hd_p.call last_lines | |
$stderr.puts "SD -> HD detected" | |
left_p = hd_p | |
right_p = sd_p | |
elsif hd_p.call first_lines and sd_p.call last_lines | |
$stderr.puts "HD -> SD detected" | |
left_p = sd_p | |
right_p = hd_p | |
end | |
if left_p.nil? or right_p.nil? | |
$stderr.puts "No switching is detected" | |
exit 0 | |
end | |
ans = bsearch( | |
0, | |
MAX_PACKETS, | |
lambda { |t| lines = avconv.skip t; left_p.call lines and not right_p.call lines and avconv.cuttable? t }, | |
lambda { |t| right_p.call avconv.skip(t) } | |
) | |
puts "tail -c +$[188*#{ans}] #{path}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment