Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dealing with start time larger than zero #334

Open
yakir12 opened this issue Sep 4, 2021 · 2 comments
Open

Dealing with start time larger than zero #334

yakir12 opened this issue Sep 4, 2021 · 2 comments

Comments

@yakir12
Copy link
Contributor

yakir12 commented Sep 4, 2021

Some videos have a start time that is larger than zero. So after reading the first frame, gettime returns a number that is much larger than expected (>>1/fps). This is very common when the recording camera split the file into ~2GB segments. In such cases, a video file will have a starting time equal to the total amount of time all the previous segments had.

It becomes a problem because most video players show the current playing time relative to the beginning of the video, i.e. zero. So if a user wants to inspect an event in the video, the time they make a note of is "wrong" and needs to be adjusted to the starting time of the video.

Is there a way to retrieve that information?

Currently I do this:

vid = VideoIO.openvideo(file)
read(vid);
t0 = gettime(vid) # now equals to the real time stamp

I can use cli ffprobe to get to that data:

ffprobe -v error -show_entries format=start_time -of default=noprint_wrappers=1:nokey=1 -i file.MTS
@yakir12
Copy link
Contributor Author

yakir12 commented Sep 6, 2021

After some careful thought, I think that there are two distinct cases here:

  1. a user has a video that s/he knows little about, tries to seek(vid, t) where t is smaller than the starting time of the video, and gets the same first frame from the video regardless of t (as long as t is smaller than the starting time).
  2. a user has a video that has been segmented into n video-files, and wants to seek into the video, either in "glabal" video-time, or in "individual" file time. This user is looking for a convenient way to do this.

Case number 1 can/should be addressed with a simple warning/info box in the documentation/FAQ.

Case number 2 warrants a more careful approach/API. Perhaps in a separate package even.

@yakir12
Copy link
Contributor Author

yakir12 commented Sep 6, 2021

I'll polish this some more tomorrow, but the following naive implementation could solve case number 2:

import VideoIO: seek, read

mutable struct SegmentedVideo
  files::Vector{String}
  videos::Vector{VideoIO.StreamContext}
  cumdur::Vector{Float64}
  current::Int
  SegmentedVideo(files::Vector{String}) = new(files, VideoIO.openvideo.(files), cumsum(VideoIO.get_duration(file) for file in files[1:end-1]), 1)
end

function VideoIO.seek(v::SegmentedVideo, t::Number)
  v.current = findfirst(<(t), v.cumdur)
  seek(v.videos[v.current], t)
end

function VideoIO.seek(v::SegmentedVideo, file::String, t::Number)
  v.current = findfirst(==(file), v.files)
  seek(v.videos[v.current], v.cumdur[v.current - 1] + t)
end

function VideoIO.read(v::SegmentedVideo) 
  if eof(v.videos[v.current]) && v.current < length(v.videos)
    v.current += 1
  end
  read(v.videos[v.current])
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant