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

Change ffmpeg argument order so that it correctly cuts at keyframes #13

Open
wants to merge 1 commit into
from

Conversation

Projects
None yet
@avh4

avh4 commented Nov 17, 2016

When I run ffmpeg with the arguments in this order -i ... -ss ... -t ..., it produces a video file that has no video for a few initial seconds. (as far as I can understand this is because it doesn't seek to a keyframe?)

If I change the order to -ss ... -i ... -t ..., then the resulting cut videos play properly.

My `ffmpeg -version`

ffmpeg version 3.2 Copyright (c) 2000-2016 the FFmpeg developers
built with Apple LLVM version 8.0.0 (clang-800.0.38)
configuration: --prefix=/usr/local/Cellar/ffmpeg/3.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-frei0r --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-librtmp --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxvid --enable-opencl --disable-lzma --enable-libopenjpeg --disable-decoder=jpeg2000 --extra-cflags=-I/usr/local/Cellar/openjpeg/2.1.2/include/openjpeg-2.1 --enable-nonfree --enable-vda
libavutil      55. 34.100 / 55. 34.100
libavcodec     57. 64.100 / 57. 64.100
libavformat    57. 56.100 / 57. 56.100
libavdevice    57.  1.100 / 57.  1.100
libavfilter     6. 65.100 /  6. 65.100
libavresample   3.  1.  0 /  3.  1.  0
libswscale      4.  2.100 /  4.  2.100
libswresample   2.  3.100 /  2.  3.100
libpostproc    54.  1.100 / 54.  1.100

@codyolsen

This comment has been minimized.

Show comment
Hide comment
@codyolsen

codyolsen Nov 17, 2016

I've had this problem too. Thanks for the work on the fix @avh4!

I've had this problem too. Thanks for the work on the fix @avh4!

@avh4

This comment has been minimized.

Show comment
Hide comment
@avh4

avh4 Nov 17, 2016

Hmm... well, I'm not sure this is actually better yet... After this change, the resulting mp4 files play correctly on Mac, but if I process them further with ffmpeg, there are still problems with the initial few seconds. I will try to experiment with this further.

avh4 commented Nov 17, 2016

Hmm... well, I'm not sure this is actually better yet... After this change, the resulting mp4 files play correctly on Mac, but if I process them further with ffmpeg, there are still problems with the initial few seconds. I will try to experiment with this further.

@avh4

This comment has been minimized.

Show comment
Hide comment
@avh4

avh4 Nov 17, 2016

So I'm having the best results atm with

      '-noaccurate_seek',
      '-ss', cutFrom,
      '-i', filePath, '-y', '-vcodec', 'copy', '-acodec', 'copy',
      '-to', cutTo,
      '-f', format,
      '-avoid_negative_ts', 'make_zero',

I'll try to set up a script to compare the effect of some of the different changes here to see what's actually best.

avh4 commented Nov 17, 2016

So I'm having the best results atm with

      '-noaccurate_seek',
      '-ss', cutFrom,
      '-i', filePath, '-y', '-vcodec', 'copy', '-acodec', 'copy',
      '-to', cutTo,
      '-f', format,
      '-avoid_negative_ts', 'make_zero',

I'll try to set up a script to compare the effect of some of the different changes here to see what's actually best.

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Nov 17, 2016

Owner

Good job! I've got some test videos/audios that I used to test with:
https://github.com/mifi/lossless-cut-fixtures
Note that many of them actually don't work in the original version either.

Owner

mifi commented Nov 17, 2016

Good job! I've got some test videos/audios that I used to test with:
https://github.com/mifi/lossless-cut-fixtures
Note that many of them actually don't work in the original version either.

@avh4

This comment has been minimized.

Show comment
Hide comment
@avh4

avh4 Nov 17, 2016

So it seems that the -noaccurate_seek is what does it.. it will cut at the nearest keyframe, but that means the cut time may be different from what you choose (in my case, by as much as 8 seconds). Because the keyframe may be before the seek time you specified, the -avoid_negative_ts make_zero adjusts all the timestamps in the output so they aren't negative (which for me caused problems later in my processing pipeline).

So I guess I'm not sure lossless-cut would want to add the -noaccurate_seek flag. It makes the times different from what you select, but then it also makes the start of the output video usable. (Another option is that ffprobe -select_streams v -show_frames <videofile> can be used to find out where the keyframes are, so possibly the UI could only let you choose cut points from the set of keyframe locations?)

I'm still investigating ways to generate a keyframe at the desired cutpoint in order to produce an output that both is cut accurately and starts with a keyframe.

avh4 commented Nov 17, 2016

So it seems that the -noaccurate_seek is what does it.. it will cut at the nearest keyframe, but that means the cut time may be different from what you choose (in my case, by as much as 8 seconds). Because the keyframe may be before the seek time you specified, the -avoid_negative_ts make_zero adjusts all the timestamps in the output so they aren't negative (which for me caused problems later in my processing pipeline).

So I guess I'm not sure lossless-cut would want to add the -noaccurate_seek flag. It makes the times different from what you select, but then it also makes the start of the output video usable. (Another option is that ffprobe -select_streams v -show_frames <videofile> can be used to find out where the keyframes are, so possibly the UI could only let you choose cut points from the set of keyframe locations?)

I'm still investigating ways to generate a keyframe at the desired cutpoint in order to produce an output that both is cut accurately and starts with a keyframe.

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Nov 17, 2016

Owner

Will the audio be shifted to be in sync with the video when using -noaccurate_seek and -avoid_negative_ts ?

I don't think it's a problem that the actual cut time is different from what you specified. Because as you say without it the part before the keyframe is useless anyways, so it has the same effect.

I actually thought about recreating the lost part after the first keyframe too, by maybe doing a re-encoding of the part between the cutpoint and the first keyframe, and then losslessly merge this part with the cut part. But then it would have to be encoded using the same parameters as the original video.

Edit: Regarding ffprobe -select_streams v -show_frames <videofile>, I was really close to implementing this (i have it in a local branch). However i found that this operation is very slow, especially for big files, so it defeats the purpose of the program being a quick way to process videos.

https://trac.ffmpeg.org/wiki/Seeking

Owner

mifi commented Nov 17, 2016

Will the audio be shifted to be in sync with the video when using -noaccurate_seek and -avoid_negative_ts ?

I don't think it's a problem that the actual cut time is different from what you specified. Because as you say without it the part before the keyframe is useless anyways, so it has the same effect.

I actually thought about recreating the lost part after the first keyframe too, by maybe doing a re-encoding of the part between the cutpoint and the first keyframe, and then losslessly merge this part with the cut part. But then it would have to be encoded using the same parameters as the original video.

Edit: Regarding ffprobe -select_streams v -show_frames <videofile>, I was really close to implementing this (i have it in a local branch). However i found that this operation is very slow, especially for big files, so it defeats the purpose of the program being a quick way to process videos.

https://trac.ffmpeg.org/wiki/Seeking

@avh4

This comment has been minimized.

Show comment
Hide comment
@avh4

avh4 Nov 18, 2016

So the problem with using -noaccurate_seek is that it will cut the video at the nearest keyframe, but the audio will be cut at the specified time.. so the resulting file will have an initial segment of audio with no video, and then the video will start at the keyframe. That seems bad too :( It seems like the only way around that is to figure out where the keyframe is and then tell ffmpeg to cut at that point.... Yeah, ffprobe is quite slow... it seems to take ~1 minute per GB for me. Maybe there are options for it, or another tool that can scan for keyframe times faster?

avh4 commented Nov 18, 2016

So the problem with using -noaccurate_seek is that it will cut the video at the nearest keyframe, but the audio will be cut at the specified time.. so the resulting file will have an initial segment of audio with no video, and then the video will start at the keyframe. That seems bad too :( It seems like the only way around that is to figure out where the keyframe is and then tell ffmpeg to cut at that point.... Yeah, ffprobe is quite slow... it seems to take ~1 minute per GB for me. Maybe there are options for it, or another tool that can scan for keyframe times faster?

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Nov 19, 2016

Owner

So is there any difference between using -noaccurate_seek and not using it? from what i can understand from your last comment, you will get the first part without video in both cases?

There has to be a faster way of detecting keyframes. If you look propietary software, they are able to generate thumbnails (presumably from keyframes) almost instantly throughout the timeline.

Owner

mifi commented Nov 19, 2016

So is there any difference between using -noaccurate_seek and not using it? from what i can understand from your last comment, you will get the first part without video in both cases?

There has to be a faster way of detecting keyframes. If you look propietary software, they are able to generate thumbnails (presumably from keyframes) almost instantly throughout the timeline.

@jpaulos

This comment has been minimized.

Show comment
Hide comment
@jpaulos

jpaulos Feb 11, 2017

From the user experience side of things, you might want to play with how the Avidemux approach feels. They "encourage" the user to split on keyframes by having the video slider automatically jump to keyframes. They also make the more obvious forward/reverse buttons be keyframe jumps. However, there are also frame-by-frame advance arrows. No idea what's going on at the backend, I'm just a "user."

jpaulos commented Feb 11, 2017

From the user experience side of things, you might want to play with how the Avidemux approach feels. They "encourage" the user to split on keyframes by having the video slider automatically jump to keyframes. They also make the more obvious forward/reverse buttons be keyframe jumps. However, there are also frame-by-frame advance arrows. No idea what's going on at the backend, I'm just a "user."

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Feb 11, 2017

Owner

Thanks for the input. I agree that we should snap to or show keyframes somehow, but I don't know how to quickly and easily get keyframe positions from the video. Using ffprobe is very slow as previously discussed.

Owner

mifi commented Feb 11, 2017

Thanks for the input. I agree that we should snap to or show keyframes somehow, but I don't know how to quickly and easily get keyframe positions from the video. Using ffprobe is very slow as previously discussed.

@Lazza

This comment has been minimized.

Show comment
Hide comment
@Lazza

Lazza Feb 12, 2017

I'm wondering if Smart Rendering could be implemented to solve this problem in the best possible way. In the past I tried to script ffmpeg and do some computations with Python scripts but it didn't work perfectly. I know for sure that Smart Cutter does this, however it's an illegal ripoff of Mencoder, FFmpeg and Xvid without any source released, so it cannot be studied.

Lazza commented Feb 12, 2017

I'm wondering if Smart Rendering could be implemented to solve this problem in the best possible way. In the past I tried to script ffmpeg and do some computations with Python scripts but it didn't work perfectly. I know for sure that Smart Cutter does this, however it's an illegal ripoff of Mencoder, FFmpeg and Xvid without any source released, so it cannot be studied.

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Feb 12, 2017

Owner

How did you do it in your python script?

I was thinking about doing something like this:
http://apple.stackexchange.com/a/176474/187402
See Lossless (but way more complicated!)

However the same problem arises, which is that ffprobe is very slow.

Owner

mifi commented Feb 12, 2017

How did you do it in your python script?

I was thinking about doing something like this:
http://apple.stackexchange.com/a/176474/187402
See Lossless (but way more complicated!)

However the same problem arises, which is that ffprobe is very slow.

@Lazza

This comment has been minimized.

Show comment
Hide comment
@Lazza

Lazza Feb 12, 2017

How did you do it in your python script?

The idea is the classic Smart Rendering approach, e.g.:

A---[-B-----C--]--D

Assume A, B, C and D are I-frames:

  • re-encode [-B using similar video quality (you can get the quality level with mediainfo, IIRC)
  • cut B-----C using -codec copy
  • re-encode C--] as above
  • use the concat filter to merge the pieces

It was almost working, then I realized not every I-frame is a keyframe (some GOPs contain back references even across I-frames) and you can only cut on "true" keyframes. But you cannot determine what the real keyframes are with ffprobe or other methods. So my code would work randomly 1 out of maybe 3 times, not very useful. Finally, I gave up.

ffprobe is very slow

What I did was to cut 2 minutes of video around my point of interest (e.g. [) with -codec copy, then use ffprobe on that piece and do the math to translate I-frame positions back to the original video. That was not very difficult, but the problem with real keyframes remains.

Lazza commented Feb 12, 2017

How did you do it in your python script?

The idea is the classic Smart Rendering approach, e.g.:

A---[-B-----C--]--D

Assume A, B, C and D are I-frames:

  • re-encode [-B using similar video quality (you can get the quality level with mediainfo, IIRC)
  • cut B-----C using -codec copy
  • re-encode C--] as above
  • use the concat filter to merge the pieces

It was almost working, then I realized not every I-frame is a keyframe (some GOPs contain back references even across I-frames) and you can only cut on "true" keyframes. But you cannot determine what the real keyframes are with ffprobe or other methods. So my code would work randomly 1 out of maybe 3 times, not very useful. Finally, I gave up.

ffprobe is very slow

What I did was to cut 2 minutes of video around my point of interest (e.g. [) with -codec copy, then use ffprobe on that piece and do the math to translate I-frame positions back to the original video. That was not very difficult, but the problem with real keyframes remains.

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Feb 12, 2017

Owner

Great explanation, thanks. That's the same way I thought of doing it.

I tried to use the read_intervals options for ffprobe, which acheives the same by seeking before printing, but it's still very slow. Just printing frame info for 10 seconds of video takes like 20 seconds on my MBP, which is way too slow.

ffprobe -print_format json -select_streams v -show_frames -read_intervals '20%+10' test.mov

Owner

mifi commented Feb 12, 2017

Great explanation, thanks. That's the same way I thought of doing it.

I tried to use the read_intervals options for ffprobe, which acheives the same by seeking before printing, but it's still very slow. Just printing frame info for 10 seconds of video takes like 20 seconds on my MBP, which is way too slow.

ffprobe -print_format json -select_streams v -show_frames -read_intervals '20%+10' test.mov

@Lazza

This comment has been minimized.

Show comment
Hide comment
@Lazza

Lazza Feb 12, 2017

Have you tried with a video file which is actually 10 seconds long?

Lazza commented Feb 12, 2017

Have you tried with a video file which is actually 10 seconds long?

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Feb 12, 2017

Owner

Yes, I tried with a DJI footage. it took 15 sec.

Owner

mifi commented Feb 12, 2017

Yes, I tried with a DJI footage. it took 15 sec.

@Lazza

This comment has been minimized.

Show comment
Hide comment
@Lazza

Lazza Feb 12, 2017

I see. Well, personally I would happily wait 1 or 2 more minutes when cutting a hour long video, if I knew I would get smart rendering... but of course other people might have different opinions on this. 😄

Also, maybe you could run ffprobe in the background when a user is dragging the marker around a certain neighborhood? That would enhance the perceived speed I guess.

Lazza commented Feb 12, 2017

I see. Well, personally I would happily wait 1 or 2 more minutes when cutting a hour long video, if I knew I would get smart rendering... but of course other people might have different opinions on this. 😄

Also, maybe you could run ffprobe in the background when a user is dragging the marker around a certain neighborhood? That would enhance the perceived speed I guess.

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Feb 13, 2017

Owner

Maybe. But it complicates things a bit. Best would be to figure out how to somehow read all keyframes superfast like Avidemux apparently does.

I found a way to speed up ffprobe a bit btw. By providing -skip_frame nokey
However it is still not very fast. maybe a 4x speed increase

Owner

mifi commented Feb 13, 2017

Maybe. But it complicates things a bit. Best would be to figure out how to somehow read all keyframes superfast like Avidemux apparently does.

I found a way to speed up ffprobe a bit btw. By providing -skip_frame nokey
However it is still not very fast. maybe a 4x speed increase

@WAZAAAAA0

This comment has been minimized.

Show comment
Hide comment
@WAZAAAAA0

WAZAAAAA0 Mar 15, 2017

If this is of any help, FFmpegYAG also known as FFmpeg Hi GUI has a way to distinguish I/P/B frames seemingly instantaneously just like Audacity, except... well, it uses FFmpeg.

https://sourceforge.net/projects/ffmpegyag/

If this is of any help, FFmpegYAG also known as FFmpeg Hi GUI has a way to distinguish I/P/B frames seemingly instantaneously just like Audacity, except... well, it uses FFmpeg.

https://sourceforge.net/projects/ffmpegyag/

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Mar 20, 2017

Owner

I've tried to use the ffmpeg command line to cut by first using ffprobe with -read_intervals to find the nearest I-frame and then pass its time value to ffmpeg -i file.mp4 -ss timevalue ...
However, when cutting on the I-frame timestamp, ffmpeg skips the desired keyframe and leaves seconds of empty video until the next keyframe. Even when going one frame back in time (the frame before I-frame), it still skips the desired keyframe. What I found kind of works is cutting 3 frames behind the I-frame. It cuts perfectly on some videos. However not on all videos. I have a local branch which implements this in LosslessCut: ffprobe-find-nearest-keyframe
I have tried to understand how ffmpeg seeking -ss really works, but not able to grasp it. And I have no idea why 3 frames behind I-frame is the magic number.

I also discovered that -noaccurate_seek only applies when encoding. It does nothing when doing -c copy.

One option might be to use the "segment" format in ffmpeg, as it seems to cut by keyframe. but it complicates things.

Owner

mifi commented Mar 20, 2017

I've tried to use the ffmpeg command line to cut by first using ffprobe with -read_intervals to find the nearest I-frame and then pass its time value to ffmpeg -i file.mp4 -ss timevalue ...
However, when cutting on the I-frame timestamp, ffmpeg skips the desired keyframe and leaves seconds of empty video until the next keyframe. Even when going one frame back in time (the frame before I-frame), it still skips the desired keyframe. What I found kind of works is cutting 3 frames behind the I-frame. It cuts perfectly on some videos. However not on all videos. I have a local branch which implements this in LosslessCut: ffprobe-find-nearest-keyframe
I have tried to understand how ffmpeg seeking -ss really works, but not able to grasp it. And I have no idea why 3 frames behind I-frame is the magic number.

I also discovered that -noaccurate_seek only applies when encoding. It does nothing when doing -c copy.

One option might be to use the "segment" format in ffmpeg, as it seems to cut by keyframe. but it complicates things.

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Mar 21, 2017

Owner

I tried to use the ffmpeg segment output format with the default segment time, but it also produces segments with the wrong length (empty video in the end of each segment), similar to cutting with ffmpeg -ss time -i file ....

Owner

mifi commented Mar 21, 2017

I tried to use the ffmpeg segment output format with the default segment time, but it also produces segments with the wrong length (empty video in the end of each segment), similar to cutting with ffmpeg -ss time -i file ....

@Lazza

This comment has been minimized.

Show comment
Hide comment
@Lazza

Lazza Mar 21, 2017

Your findings about ffmpeg match my experiments I did in the past. That's also because not every I-frame is a keyframe, unfortunately... 😭

Lazza commented Mar 21, 2017

Your findings about ffmpeg match my experiments I did in the past. That's also because not every I-frame is a keyframe, unfortunately... 😭

@mifi mifi added the keyframe-cut label Mar 26, 2017

@eexpress

This comment has been minimized.

Show comment
Hide comment
@eexpress

eexpress Mar 27, 2017

I think we need add two tool icons, which jump to last/next keyframe. like in avidemux.
wait for issues26 and issues13 solve.
I like this KISS software.

I think we need add two tool icons, which jump to last/next keyframe. like in avidemux.
wait for issues26 and issues13 solve.
I like this KISS software.

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Mar 27, 2017

Owner

Yes that should be fairly trivial to implement but not very useful until we figure out how to actually cut on keyframes

Owner

mifi commented Mar 27, 2017

Yes that should be fairly trivial to implement but not very useful until we figure out how to actually cut on keyframes

@modest

This comment has been minimized.

Show comment
Hide comment
@modest

modest Apr 4, 2017

FYI, I believe there is a slightly hacky way to get even closer to what you're trying to accomplish.

While it's true that you must trim at GOP boundaries, you don't necessarily need to display all of those frames. In the mp4 headers that you write, you can "mute" frames at the beginning and end by setting their duration to 0 in the stts (Sample to Time) table.

These 0-duration frames will be available for reference by other frames, but will not play. (Make sure to drop audio frames appropriately, too.)

The "right" way to do this is with mp4/mov Edit List metadata (elst box), which were specifically designed for lossless video trimming. Unfortunately they aren't well-supported in .mp4, so compatibility varies…

modest commented Apr 4, 2017

FYI, I believe there is a slightly hacky way to get even closer to what you're trying to accomplish.

While it's true that you must trim at GOP boundaries, you don't necessarily need to display all of those frames. In the mp4 headers that you write, you can "mute" frames at the beginning and end by setting their duration to 0 in the stts (Sample to Time) table.

These 0-duration frames will be available for reference by other frames, but will not play. (Make sure to drop audio frames appropriately, too.)

The "right" way to do this is with mp4/mov Edit List metadata (elst box), which were specifically designed for lossless video trimming. Unfortunately they aren't well-supported in .mp4, so compatibility varies…

@StefRe

This comment has been minimized.

Show comment
Hide comment
@StefRe

StefRe Jun 13, 2017

To be absolutely on the safe side we’ll have to cut at IDR frames only (not every I frame is an IDR frame: hardangerbrua-dji-phantom.mp4 for instance contains 20 I frames but only 5 of them are IDR frames). As you noticed, P and B frames after a non-IDR I frame can refer to frames before that I frame (max_num_ref_frames which can theoretically be as big as 16).

IDR frame time stamps can be extracted with
ffprobe hardangerbrua-dji-phantom.mp4 -show_packets -show_entries packet=pts_time,flags -of csv | grep ",K" | cut -d ',' -f 2

Show packets is also way faster than show frames. The only drawback is that we may end up with only a few places to cut the video.

StefRe commented Jun 13, 2017

To be absolutely on the safe side we’ll have to cut at IDR frames only (not every I frame is an IDR frame: hardangerbrua-dji-phantom.mp4 for instance contains 20 I frames but only 5 of them are IDR frames). As you noticed, P and B frames after a non-IDR I frame can refer to frames before that I frame (max_num_ref_frames which can theoretically be as big as 16).

IDR frame time stamps can be extracted with
ffprobe hardangerbrua-dji-phantom.mp4 -show_packets -show_entries packet=pts_time,flags -of csv | grep ",K" | cut -d ',' -f 2

Show packets is also way faster than show frames. The only drawback is that we may end up with only a few places to cut the video.

@Lazza

This comment has been minimized.

Show comment
Hide comment
@Lazza

Lazza Jun 13, 2017

The only drawback is that we may end up with only a few places to cut the video.

Actually your method sounds great because one could do a lossless cut between IDR frames and then reencode just a small portion of the video before and after them.

Lazza commented Jun 13, 2017

The only drawback is that we may end up with only a few places to cut the video.

Actually your method sounds great because one could do a lossless cut between IDR frames and then reencode just a small portion of the video before and after them.

@dimso

This comment has been minimized.

Show comment
Hide comment
@dimso

dimso Jun 25, 2017

I am having the same issue - during the first 2 seconds of video playback I can only hear audio and there is no video. I cannot make a cut a couple frames before because it is a b-roll. So, I would love to see an option to re-encode small parts of video at the begging and end if needed.

dimso commented Jun 25, 2017

I am having the same issue - during the first 2 seconds of video playback I can only hear audio and there is no video. I cannot make a cut a couple frames before because it is a b-roll. So, I would love to see an option to re-encode small parts of video at the begging and end if needed.

@zackurben

This comment has been minimized.

Show comment
Hide comment
@zackurben

zackurben Sep 24, 2017

@mifi I would love to help on this issue, as it's something I noticed pretty quickly. Has any other progress been made, or is this thread the most up-to-date info? Cheers ✌️

@mifi I would love to help on this issue, as it's something I noticed pretty quickly. Has any other progress been made, or is this thread the most up-to-date info? Cheers ✌️

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Sep 25, 2017

Owner

Hi @zackurben!

This is the most recent discussion, yes. I tried @StefRe's suggestion of finding IDR frames, and then I tried to cut from some of these. If I reorder -ss -i like in @avh4's first post, it seems to be working on hardangerbrua-dji-phantom.mp4 at least. So we might be onto something

Edit: For some videos I get up to a few seconds of audio without video in the ending of the video.

Owner

mifi commented Sep 25, 2017

Hi @zackurben!

This is the most recent discussion, yes. I tried @StefRe's suggestion of finding IDR frames, and then I tried to cut from some of these. If I reorder -ss -i like in @avh4's first post, it seems to be working on hardangerbrua-dji-phantom.mp4 at least. So we might be onto something

Edit: For some videos I get up to a few seconds of audio without video in the ending of the video.

@gleddamax

This comment has been minimized.

Show comment
Hide comment
@gleddamax

gleddamax Nov 21, 2017

If the cut start point is 0, cutting only at the end of the video, the solution is not to use the -ss option in the command line for ffmpeg. When using -ss 0.000 (or similar), the cutted videos are shown with a black part at the beginning.
But for the main problem I also have no solution (yet).

If the cut start point is 0, cutting only at the end of the video, the solution is not to use the -ss option in the command line for ffmpeg. When using -ss 0.000 (or similar), the cutted videos are shown with a black part at the beginning.
But for the main problem I also have no solution (yet).

@mhavo

This comment has been minimized.

Show comment
Hide comment
@mhavo

mhavo Nov 21, 2017

Would it be possible to change ffmpeg to work right? Or maybe new option in ffmpeg. I have major issues with this problem also...

mhavo commented Nov 21, 2017

Would it be possible to change ffmpeg to work right? Or maybe new option in ffmpeg. I have major issues with this problem also...

@mifi mifi referenced this pull request Nov 21, 2017

Closed

Don't cut at -ss 0 #50

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Nov 21, 2017

Owner

Started a new issue for -ss 0 here: #50

Owner

mifi commented Nov 21, 2017

Started a new issue for -ss 0 here: #50

@gleddamax

This comment has been minimized.

Show comment
Hide comment
@gleddamax

gleddamax Nov 21, 2017

an explanation how the -ssoption works you can find on https://ffmpeg.org/ffmpeg-all.html#Main-options:

-ss position (input/output)

When used as an input option (before -i), seeks in this input file to position. Note that in most formats
it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position.
When
transcoding and -accurate_seek is enabled (the default), this extra segment between the seek point and
position will be decoded and discarded. When doing stream copy or when -noaccurate_seek is used, it
will be preserved.

When used as an output option (before an output url), decodes but discards input until the
timestamps reach position.

e.g. -i input_file -ss 12.678 -to ... output -ss is taken for the encoder/output file --> cut more accurate but maybe black parts in the video because of missing I(DR) frames especially at the beginning of the video.

A less accurate cut you get by putting the -ss ... before the input file -i ... (e.g. -ss 12.678 -i input_file -to ...). It is taken for the decoder/ input file and should result in a video file without black parts (especially at the beginning).

an explanation how the -ssoption works you can find on https://ffmpeg.org/ffmpeg-all.html#Main-options:

-ss position (input/output)

When used as an input option (before -i), seeks in this input file to position. Note that in most formats
it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position.
When
transcoding and -accurate_seek is enabled (the default), this extra segment between the seek point and
position will be decoded and discarded. When doing stream copy or when -noaccurate_seek is used, it
will be preserved.

When used as an output option (before an output url), decodes but discards input until the
timestamps reach position.

e.g. -i input_file -ss 12.678 -to ... output -ss is taken for the encoder/output file --> cut more accurate but maybe black parts in the video because of missing I(DR) frames especially at the beginning of the video.

A less accurate cut you get by putting the -ss ... before the input file -i ... (e.g. -ss 12.678 -i input_file -to ...). It is taken for the decoder/ input file and should result in a video file without black parts (especially at the beginning).

@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Nov 21, 2017

Owner

A less accurate cut you get by putting the -ss ... before the input file -i ... (e.g. -ss 12.678 -i input_file -to ...). It is taken for the decoder/ input file and should result in a video file without black parts (especially at the beginning).

So I tried this, as I commented previously in this thread, but it seems to cause a part at the end of the video to be problematic instead.

Owner

mifi commented Nov 21, 2017

A less accurate cut you get by putting the -ss ... before the input file -i ... (e.g. -ss 12.678 -i input_file -to ...). It is taken for the decoder/ input file and should result in a video file without black parts (especially at the beginning).

So I tried this, as I commented previously in this thread, but it seems to cause a part at the end of the video to be problematic instead.

@Lazza

This comment has been minimized.

Show comment
Hide comment
@mifi

This comment has been minimized.

Show comment
Hide comment
@mifi

mifi Nov 30, 2017

Owner

I don't have much time these days, but if someone can figure out and explain how VidCutter does this, that would be nice. Or rather how, and IF it is even even actually able to cut accurately on keyframes.
I might be able to look into it next month.

Owner

mifi commented Nov 30, 2017

I don't have much time these days, but if someone can figure out and explain how VidCutter does this, that would be nice. Or rather how, and IF it is even even actually able to cut accurately on keyframes.
I might be able to look into it next month.

@Lazza

This comment has been minimized.

Show comment
Hide comment

Lazza commented Dec 2, 2017

@mifi mifi referenced this pull request Feb 11, 2018

Open

merge multiple videos #7

@AgostinoSturaro

This comment has been minimized.

Show comment
Hide comment
@AgostinoSturaro

AgostinoSturaro Mar 6, 2018

I found your program, and the following QnA searching for a lossless video cutter. The most voted answer suggests using ffmpeg, like you do.

https://softwarerecs.stackexchange.com/q/25741

After reading this discussion, I'm not sure if it's correct. If that's the case, can it help solve this issue?

I found your program, and the following QnA searching for a lossless video cutter. The most voted answer suggests using ffmpeg, like you do.

https://softwarerecs.stackexchange.com/q/25741

After reading this discussion, I'm not sure if it's correct. If that's the case, can it help solve this issue?

@bnku

This comment has been minimized.

Show comment
Hide comment
@bnku

bnku Mar 12, 2018

without solving this problem, it is impossible to use the program :(

bnku commented Mar 12, 2018

without solving this problem, it is impossible to use the program :(

@akovia

This comment has been minimized.

Show comment
Hide comment
@akovia

akovia Mar 16, 2018

I've read through this thread and certainly don't have the answer for the perfect fix, but I noticed there are ways to make trade-offs depending on the ffmpeg options and order thereof.

I would propose exposing the commandline for a simple way for people to experiment easily and provide feedback without having to building code to do so. This could also make the program a perfect fit as it is for some people. I personally don't need audio at all as I am just cutting video clips to make videos. Just making certain the in and out points I selected are included in the output would be huge. I can easily trim them up in blender when making my video. As it is now, I have to find my points and add 10 seconds to each end just to be safe, making it cumbersome to use.

If exposing the CLI is a bad idea for some reason, maybe the option to select from a couple pre-defined modes that utilize what has been discussed here.

Lastly, I personally would have no qualms about waiting a few minutes for everything to be indexed properly if the results could be relied upon. I can do something else while it is indexing, but I would like the option to cache the results somehow as I do switch back and forth between sources and wouldn't want to index the same video twice in the same session.

I should have started with this, but I love the program! Hope it can get some love to be all it can be.

akovia commented Mar 16, 2018

I've read through this thread and certainly don't have the answer for the perfect fix, but I noticed there are ways to make trade-offs depending on the ffmpeg options and order thereof.

I would propose exposing the commandline for a simple way for people to experiment easily and provide feedback without having to building code to do so. This could also make the program a perfect fit as it is for some people. I personally don't need audio at all as I am just cutting video clips to make videos. Just making certain the in and out points I selected are included in the output would be huge. I can easily trim them up in blender when making my video. As it is now, I have to find my points and add 10 seconds to each end just to be safe, making it cumbersome to use.

If exposing the CLI is a bad idea for some reason, maybe the option to select from a couple pre-defined modes that utilize what has been discussed here.

Lastly, I personally would have no qualms about waiting a few minutes for everything to be indexed properly if the results could be relied upon. I can do something else while it is indexing, but I would like the option to cache the results somehow as I do switch back and forth between sources and wouldn't want to index the same video twice in the same session.

I should have started with this, but I love the program! Hope it can get some love to be all it can be.

aitte2 referenced this pull request in mgp25/Instagram-API Mar 23, 2018

Media: Support custom video thumbnail timestamps
Closes #1831

Massive thanks to @tje3d who started the process of making this change,
but it unfortunately became a bit messy by the end. But the fact that he
started the work is the only reason that this feature exists now! Also
thanks to @valga for discussion and great ideas!

This commit does the following changes:

- Refactored `InstagramVideo` class to support adding both input-file
  flags and output-file flags (instead of only output-file flags), and
  made those functions return arrays for easier handling. This change
  was necessary for fast thumbnail seeking. Otherwise (if `-ss` is
  specified after the input file), ffmpeg converts the whole file up
  until the desired timestamp which is a big waste of time. ;)

- The `Internal` class now gives the optional `thumbnail_timestamp`
  `$externalMetadata` value into the constructor of `InstagramThumbnail`
  if a custom timestamp has been provided by the user.

- `InstagramThumbnail` now supports a "thumbnailTimestamp" option (note
  the different spelling for our internal name), which is only applied
  if the target feed for the video is TIMELINE (exactly like the real
  app). The thumbnail class converts and validates the given timestamp
  and ensures it's within a legal range, and then provides 3 ways to use
  the timestamp after that: `getFile()` to generate a jpeg thumbnail
  file as usual (but with the custom timestamps now), or
  `getTimestamp()` to get the validated timestamp as a float (useful by
  valga when implementing `cover_frame_seek` server-side cover
  generation later), and `getTimestampString()` which gets it as a
  ffmpeg-style string instead.

For users:

Your custom thumbnail timestamps can only be provided for timeline
videos (`$ig->timeline->uploadVideo()`). Not for any other video types
and not for any albums. This is intentional to match the real app.

You can provide the timestamp value as a float or as a time string.

Examples (both use 1.5 seconds as the cover timestamp location):

```
$ig->timeline->uploadVideo('example.mp4', ['thumbnail_timestamp' => 1.5]);
$ig->timeline->uploadVideo('example.mp4', ['thumbnail_timestamp' => '00:00:01.500']);
```

If your timestamp position is longer than the video, the final frame of
the video is used. So you don't have to worry about that.
@GeoDecouvreTout

This comment has been minimized.

Show comment
Hide comment
@GeoDecouvreTout

GeoDecouvreTout Apr 4, 2018

VidCutter 5 lets you create frame accurate cuts using the new "SmartCut" feature. But this feature makes use of re-encoding which makes losing the initial interest of this kind of software.

A possible workaround for mp4 files (not tested with other formats):

  1. Use LosslessCut to export your selection.
  2. Import the output video in VidCutter to export it again (without using the "SmartCut" feature i.e. using the default lossless mode).

I don't know why but there is no more empty portion in the beginning of the final video. Probably because VidCutter uses different arguments...

GeoDecouvreTout commented Apr 4, 2018

VidCutter 5 lets you create frame accurate cuts using the new "SmartCut" feature. But this feature makes use of re-encoding which makes losing the initial interest of this kind of software.

A possible workaround for mp4 files (not tested with other formats):

  1. Use LosslessCut to export your selection.
  2. Import the output video in VidCutter to export it again (without using the "SmartCut" feature i.e. using the default lossless mode).

I don't know why but there is no more empty portion in the beginning of the final video. Probably because VidCutter uses different arguments...

@Lazza

This comment has been minimized.

Show comment
Hide comment
@Lazza

Lazza Apr 4, 2018

@GeoDecouvreTout the smart cutting feature of VidCutter only encodes the two GOPs that are cut in the middle. It does not encode the rest, so it implements smart cutting correctly.

Lazza commented Apr 4, 2018

@GeoDecouvreTout the smart cutting feature of VidCutter only encodes the two GOPs that are cut in the middle. It does not encode the rest, so it implements smart cutting correctly.

@GeoDecouvreTout

This comment has been minimized.

Show comment
Hide comment
@GeoDecouvreTout

GeoDecouvreTout Apr 21, 2018

@Lazza :

  1. Strangely, this possible workaround works very well with some files and not at all with others. I'm just wondering why…

  2. The smart cutting feature of VidCutter v5.5.0 would be perfect. Unfortunately, in my case, it re-encodes the whole selection with a significant quality loss. It takes a lot of time and it sometimes hangs. Next versions will probably correct the problem...

GeoDecouvreTout commented Apr 21, 2018

@Lazza :

  1. Strangely, this possible workaround works very well with some files and not at all with others. I'm just wondering why…

  2. The smart cutting feature of VidCutter v5.5.0 would be perfect. Unfortunately, in my case, it re-encodes the whole selection with a significant quality loss. It takes a lot of time and it sometimes hangs. Next versions will probably correct the problem...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment