Class: Kaede::Recorder

Inherits:
Object
  • Object
show all
Defined in:
lib/kaede/recorder.rb

Constant Summary collapse

BUFSIZ =
188 * 16

Instance Method Summary collapse

Constructor Details

#initialize(notifier) ⇒ Recorder

Returns a new instance of Recorder.



7
8
9
# File 'lib/kaede/recorder.rb', line 7

def initialize(notifier)
  @notifier = notifier
end

Instance Method Details

#after_record(program) ⇒ Object



123
124
125
126
127
128
129
# File 'lib/kaede/recorder.rb', line 123

def after_record(program)
  @notifier.notify_after_record(program)
  move_ass_to_cabinet(program)
  clean_ts(program)
  enqueue_to_redis(program)
  FileUtils.rm(cache_path(program).to_s)
end

#before_record(program) ⇒ Object



119
120
121
# File 'lib/kaede/recorder.rb', line 119

def before_record(program)
  @notifier.notify_before_record(program)
end

#cabinet_ass_path(program) ⇒ Object



42
43
44
# File 'lib/kaede/recorder.rb', line 42

def cabinet_ass_path(program)
  Kaede.config.cabinet_dir.join("#{program.formatted_fname}.raw.ass")
end

#cabinet_path(program) ⇒ Object



38
39
40
# File 'lib/kaede/recorder.rb', line 38

def cabinet_path(program)
  Kaede.config.cabinet_dir.join("#{program.formatted_fname}.ts")
end

#cache_ass_path(program) ⇒ Object



34
35
36
# File 'lib/kaede/recorder.rb', line 34

def cache_ass_path(program)
  Kaede.config.cache_dir.join("#{program.tid}_#{program.pid}.raw.ass")
end

#cache_path(program) ⇒ Object



30
31
32
# File 'lib/kaede/recorder.rb', line 30

def cache_path(program)
  Kaede.config.cache_dir.join("#{program.tid}_#{program.pid}.cache.ts")
end

#calculate_duration(program) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/kaede/recorder.rb', line 62

def calculate_duration(program)
  duration = (program.end_time - program.start_time).to_i - 10
  end_datetime = program.end_time.to_datetime
  if end_datetime.sunday? && end_datetime.hour == 22 && end_datetime.min == 27
    # For MX
    duration += 3 * 60
  elsif program.channel_name =~ /NHK/
    # For NHK
    duration += 25
  end
  duration
end

#clean_ts(program) ⇒ Object



140
141
142
143
144
# File 'lib/kaede/recorder.rb', line 140

def clean_ts(program)
  unless system(Kaede.config.clean_ts.to_s, cache_path(program).to_s, cabinet_path(program).to_s)
    raise "clean-ts failure: #{program.formatted_fname}"
  end
end

#do_record(program) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/kaede/recorder.rb', line 46

def do_record(program)
  spawn_recpt1(program)
  spawn_tail(program)
  spawn_b25(program)
  spawn_ass(program)
  spawn_repeater
  wait_recpt1
  finalize
end

#enqueue_to_redis(program) ⇒ Object



146
147
148
# File 'lib/kaede/recorder.rb', line 146

def enqueue_to_redis(program)
  Kaede.config.redis.rpush(Kaede.config.redis_queue, program.formatted_fname)
end

#finalizeObject



111
112
113
114
115
116
117
# File 'lib/kaede/recorder.rb', line 111

def finalize
  Process.kill(:INT, @tail_pid)
  Process.waitpid(@tail_pid)
  @repeater_thread.join
  Process.waitpid(@b25_pid)
  Process.waitpid(@ass_pid)
end

#move_ass_to_cabinet(program) ⇒ Object



131
132
133
134
135
136
137
138
# File 'lib/kaede/recorder.rb', line 131

def move_ass_to_cabinet(program)
  ass_path = cache_ass_path(program)
  if ass_path.size == 0
    ass_path.unlink
  else
    FileUtils.mv(ass_path.to_s, cabinet_ass_path(program).to_s)
  end
end

#record(db, pid) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/kaede/recorder.rb', line 11

def record(db, pid)
  program = db.get_program(pid)
  before_record(program)

  puts "Start #{pid} #{program.syoboi_url}"
  do_record(program)

  program = db.get_program(pid)
  puts "Done #{pid} #{program.syoboi_url}"
  after_record(program)
rescue Exception => e
  @notifier.notify_exception(e, program)
  raise e
end

#record_path(program) ⇒ Object



26
27
28
# File 'lib/kaede/recorder.rb', line 26

def record_path(program)
  Kaede.config.record_dir.join("#{program.tid}_#{program.pid}.ts")
end

#spawn_ass(program) ⇒ Object



87
88
89
90
91
# File 'lib/kaede/recorder.rb', line 87

def spawn_ass(program)
  @ass_pipe_r, @ass_pipe_w = IO.pipe
  @ass_pid = spawn(Kaede.config.assdumper.to_s, '/dev/stdin', in: @ass_pipe_r, out: cache_ass_path(program).to_s)
  @ass_pipe_r.close
end

#spawn_b25(program) ⇒ Object



81
82
83
84
85
# File 'lib/kaede/recorder.rb', line 81

def spawn_b25(program)
  @b25_pipe_r, @b25_pipe_w = IO.pipe
  @b25_pid = spawn(Kaede.config.b25.to_s, '-v0', '-s1', '-m1', '/dev/stdin', cache_path(program).to_s, in: @b25_pipe_r)
  @b25_pipe_r.close
end

#spawn_recpt1(program) ⇒ Object



56
57
58
59
60
# File 'lib/kaede/recorder.rb', line 56

def spawn_recpt1(program)
  path = record_path(program)
  path.open('w') {}
  @recpt1_pid = spawn(Kaede.config.recpt1.to_s, program.channel_for_recorder.to_s, calculate_duration(program).to_s, path.to_s)
end

#spawn_repeaterObject



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/kaede/recorder.rb', line 95

def spawn_repeater
  @repeater_thread = Thread.start do
    while buf = @tail_pipe_r.read(BUFSIZ)
      @b25_pipe_w.write(buf)
      @ass_pipe_w.write(buf)
    end
    @tail_pipe_r.close
    @b25_pipe_w.close
    @ass_pipe_w.close
  end
end

#spawn_tail(program) ⇒ Object



75
76
77
78
79
# File 'lib/kaede/recorder.rb', line 75

def spawn_tail(program)
  @tail_pipe_r, @tail_pipe_w = IO.pipe
  @tail_pid = spawn('tail', '-f', record_path(program).to_s, out: @tail_pipe_w)
  @tail_pipe_w.close
end

#wait_recpt1Object



107
108
109
# File 'lib/kaede/recorder.rb', line 107

def wait_recpt1
  Process.waitpid(@recpt1_pid)
end