Method: Platform#capture_frames

Defined in:
lib/platform/platform.rb

#capture_frames(duration, args = {}) ⇒ Object

Public: Captures frames on the device.

duration - Integer total milliseconds to capture frames. key - String name or Array of keys to press to trigger audio capture (default: nil).

If default, no keys will be pressed.

delay - Integer milliseconds to delay after pressing key and before starting frame capture (default: 0). cleanup - Boolean indicating whether to automatically clean up frames during teardown (default: true).

If true, all frames in the output which have :keep => false will be deleted at the end of the test.

Returns a Hash with the following keys: :frames - Array of captured frames, each being a Hash with the following keys:

:filename   - String full path to the frame on the server.
:capturedAt - Time at which the frame was captured.
:keep       - Boolean indicating whether to keep the frame if cleanup is true. Initializes false.

:start_time - Time at which frame capture began.



615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
# File 'lib/platform/platform.rb', line 615

def capture_frames(duration, args={})
  key = args[:key]
  cleanup = args.fetch(:cleanup, true)
  frames = []
  if cleanup
    @test_case.add_teardown('Cleaning up captured frames', frames) do |frame_arr|
      delete_files = frame_arr.reject { |frm| frm[:keep] }.map { |frm| frm[:filename] }
      json = get_json_for_test.merge(files: delete_files)
      @test_case.send(:tmc_delete, '/api/images', json: json)
    end
  end
  # Capture frames
  delay = args.fetch(:delay, 0)
  ret = {}
  if key.nil?
    # this is the best we can do since there is no key. as long as the script runs locally on the TMC,
    # we do not need to worry about clock drift issues
    ret[:start_time] = Time.now
  else
    # use the key press time
    ret[:start_time] = press_key(key, sleep_time: 0) unless key.nil?
  end
  if delay > 0
    sleep(delay)
  end
  json = get_json_for_iter.merge(durationMs: duration)
  result = @test_case.send(:tmc_post, "/api/images/record/#{@id}", json: json)
  raise 'Failed to capture frames!' if result.nil?
  #ret[:start_time] ||= @test_case.to_time(result['startTime'])  # use this start time ONLY if no key and no delay
  result.fetch('images').each do |frm|
    capture_time = frm.fetch('captureTime')
    capture_time = capture_time / 1000.0 unless capture_time.is_a?(String)
    frames << {filename: frm.fetch('path'), capturedAt: @test_case.to_time(capture_time), keep: false}
  end
  ret[:frames] = frames
  # Calculate average FPS and maximum/average margin of error
  max_i, max = [0, 0]
  frame_deltas = frames.each_with_index.map do |f, i|
    if i == 0
      delta = @test_case.get_time_delta(ret[:start_time], f[:capturedAt])
    else
      delta = @test_case.get_time_delta(frames[i - 1][:capturedAt], f[:capturedAt])
    end
    if delta > max
      max_i, max = [i, delta]
    end
    delta
  end
  deltas_sum = frame_deltas.inject(0) {|sum, x| sum + x}
  sec = deltas_sum / 1000.0
  avg_fps = frames.count / sec
  avg_delta = deltas_sum / frame_deltas.count
  logger.debug("Captured #{frames.count} frames in #{sec} s [avg frames/s: #{avg_fps}, " +
                   "max error: #{max} ms (frame #{max_i}), avg error: #{avg_delta} ms]")
  ret
end