mifi / lossless-cut

The swiss army knife of lossless video/audio editing
https://losslesscut.app/
GNU General Public License v2.0
26.14k stars 1.26k forks source link

Merging two .mp4 files results in a file the same duration as the first file. #1680

Closed Monkeor closed 9 months ago

Monkeor commented 1 year ago

I have a lot of issues to go through, so in order to make it easier for me to help you, I ask that you please try these things first

Operating System

Windows 10

Steps to reproduce

I have 2 .mp4 files, one 3.67gb and one 2.90gb, which I'm trying to merge. I import them and hit merge, but the software gives me this error showing that the output file is much shorter than the sum of the two input files. image

I tried disabling all tracks except for the video tracks (though it seemed like going to disable the audio track of the second clip re-enabled the audio track of the first clip and vice-versa?), I tried every setting of avoid_negative_ts in the export settings, and I've tried exporting both videos and merging those instead. Nothing has worked.

Expected behavior

The two files should merge into one single file instead of not doing that.

Actual behavior

Final file is just a copy of the first file with the same duration.

Share log

No response

mifi commented 1 year ago

that's odd. how does your merge options look like? also, can you provide some more info? see https://github.com/mifi/lossless-cut/issues/new?assignees=&labels=&projects=&template=file-issue.yml

mifi commented 1 year ago

did you try to open each file separately, then for each file: disable all tracks except video, then export? and then merge the resulting two exported files?

Monkeor commented 1 year ago

I just tried exporting each half separately through LosslessCut after disabling the audio tracks (the only track that the files had other than the video) and trying to merge those, but the same error occurs.

These are my merge options: image

This is the error report from Help->Report an Error:

No error occurred.

{
  "state": {
    "ffmpegExperimental": false,
    "preserveMovData": false,
    "movFastStart": true,
    "preserveMetadataOnMerge": false,
    "filePath": "",
    "externalFilesMeta": {},
    "mainStreams": [],
    "copyStreamIdsByFile": {},
    "cutSegments": [
      {}
    ],
    "mainFileFormatData": {},
    "rotation": 360,
    "shortestFlag": false,
    "effectiveExportMode": "separate",
    "outSegTemplate": "${FILENAME}-${CUT_FROM}-${CUT_TO}${SEG_SUFFIX}${EXT}"
  },
  "platform": "win32",
  "version": "3.54.0"
}

This is the log from the Javascript console: image

This is a GDrive link to the two files I'm trying to merge: https://drive.google.com/drive/folders/1gmDQ3h_8pcpRmVF93MtXhuQ6FhZZBtMS?usp=sharing

I hope this covers everything you're looking for, but if not, let me know.

mifi commented 1 year ago

Thanks for sharing. I found the problem:

When running this ffmpeg command (copy from "last ffmpeg commands")

echo -e "file 'file:TEST-001.mp4'\nfile 'file:TEST2-002.mp4'" | ffmpeg -hide_banner -f concat -safe 0 -protocol_whitelist 'file,pipe,fd' -i - -map 0 -c copy -f mp4 -y 'TEST-001-merged-1692298808211.mp4'

I get this output:

...
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x139705250] Auto-inserting h264_mp4toannexb bitstream filter
...
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x142704a20] st: 0 edit list: 1 Missing key frame while searching for timestamp: 0
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x142704a20] st: 0 edit list 1 Cannot find an index entry before timestamp: 0.
...
[concat @ 0x139704e90] h264_mp4toannexb filter failed to receive output packet
Error demuxing input file 0: Invalid data found when processing input
fd:: Invalid data found when processing input

however ffmpeg exits with exit code 0, meaning the operation succeeded, so LosslessCut thinks the cut succeeded. But as you say, the second file TEST2-002.mp4 is ignored and not included in the output.

If I run the command again but append -auto_convert 0 (which doesn't auto-insert h264_mp4toannexb) to the concat demuxer options, then it works.

I believe this is a bug in ffmpeg. We could add -auto_convert 0 for everyone, as it seems to only be needed for mpegts, but it doesn't feel right: If I try to merge to mpegts (with -auto_convert 0), I'm getting this error:

[mpegts @ 0x128704fd0] Error applying bitstream filters to an output packet for stream #0: Invalid data found when processing input
av_interleaved_write_frame(): Invalid data found when processing input
[out#0/mpegts @ 0x600001394000] Error muxing a packet

I think the problematic file is TEST-001.mp4. If I run this

ffmpeg -i TEST-001.mp4 -c copy -bsf:v h264_mp4toannexb TEST-001-annexb.mp4

it gives an error:

[vost#0:0/copy @ 0x120e0ff60] Error applying bitstream filters to a packet.0kbits/s speed= 100x    

however the export succeeds. Probably there's a problematic/corrupt frame/packet in your file.

If I take the exported TEST-001-annexb.mp4 file and merge it with TEST2-002.mp4, then it works.

I think we should add an advanced expoort option in losslesscut to add -bsf:v h264_mp4toannexb to the export. However for now you have to run the above command yourself.

Monkeor commented 1 year ago

image I tried running the command through Losslesscut's console, but it doesn't seem to work. How exactly do I run this command to merge the files myself?

mifi commented 1 year ago

You have to install ffmpeg and run it from cmd

Monkeor commented 1 year ago

image I hate to come back with what might be an unrelated issue, but the protocol_whitelist flag doesn't seem to be working for fd and I don't know why. The full command I'm running is:

echo -e "file 'file:G:\Shadowplay recordings\Devil May Cry 5\DMD Guns Only\TEST.mp4'\nfile 'file:G:\Shadowplay recordings\Devil May Cry 5\DMD Guns Only\TEST2.mp4'" | ffmpeg -hide_banner -f concat -auto_convert 0 -safe 0 -protocol_whitelist 'file,pipe,fd' -i - -map 0 -c copy -f mp4 -y 'MERGED.mp4'

It doesn't seem to make a difference whether I try the same thing on the two files exported from LosslessCut with the audio channels removed either. image

mifi commented 1 year ago

not sure why you need to run that command. instead run this command:

ffmpeg -i TEST-001.mp4 -c copy -bsf:v h264_mp4toannexb TEST-001-annexb.mp4

then merge the resulting file with test2 using losslesscut

Monkeor commented 1 year ago

Thank you, this worked for me. You've been a huge help.

mifi commented 1 year ago

nice! for future reference: in latest llc version people can add h264_mp4toannexb in the "tracks" panel