thenickdude / webm-writer-js

JavaScript-based WebM video encoder for Google Chrome
272 stars 43 forks source link

Generated webm not working in WhatsApp/Vlc #22

Closed mst2020 closed 3 years ago

mst2020 commented 3 years ago

Hello & thanks for this little nice tool!

The generated webm file is not playable by vlc/WhatsApp other tools, even ffmpeg can't convert it. Its also not possible to share it via WhatsApp etc pp because of "unsupported file format". All those things are working when using a webm file from here: https://www.webmfiles.org/demo-files

So in my naive understanding :), it should also work with those files created by this lib? (or not?)

In my opinion the file is created successfully. It is created out of 4 single pictures (canvas) with 1fps. (maybe short webm need special header or smth?)

I attached the test file: test.zip

Where can i take a look to gain more information about the possible error?

Thanks for your help!

ffmpeg

Input #0, matroska,webm, from 'test.webm':
  Metadata:
    encoder         : webm-writer-js
  Duration: 00:00:04.00, start: 0.000000, bitrate: 4849 kb/s
    Stream #0:0: Video: vp8, yuv420p(progressive), 1680x882, SAR 1:1 DAR 40:21, 1 fps, 1 tbr, 1k tbn, 1k tbc (default)

exiftool:

ExifTool Version Number         : 11.88
File Name                       : test.webm
Directory                       : .
File Size                       : 2.3 MB
File Modification Date/Time     : 2020:10:14 16:56:22+02:00
File Access Date/Time           : 2020:10:14 16:56:37+02:00
File Inode Change Date/Time     : 2020:10:14 16:56:31+02:00
File Permissions                : rw-rw-r--
File Type                       : WEBM
File Type Extension             : webm
MIME Type                       : video/webm
EBML Version                    : 1
EBML Read Version               : 1
Doc Type                        : webm
Doc Type Version                : 2
Doc Type Read Version           : 2
Timecode Scale                  : 1 ms
Muxing App                      : webm-writer-js
Writing App                     : webm-writer-js
Duration                        : 4.00 s
Track Number                    : 1
Track Language                  : und
Codec ID                        : V_VP8
Codec Name                      : VP8
Track Type                      : Video
Image Width                     : 1680
Image Height                    : 882
Image Size                      : 1680x882
Megapixels                      : 1.5
guest271314 commented 3 years ago

The generated webm file is not playable by other tools, even ffmpeg can't convert it.

Cannot reproduce

$ mpv test.webm

Screenshot_2020-10-16_10-10-01

ffplay test.webm

Screenshot_2020-10-16_10-10-29

Firefox 81 (64-bit) Screenshot_2020-10-16_10-14-12

mst2020 commented 3 years ago

Hello & thanks for your efforts.

You are right, and i'm a little bit ashamed, i can convert it with ffmpeg (i did something wrong) and ffplay is working well.

It seems to me that there is a little difference between the "test.webm" and for example http://dl5.webmfiles.org/big-buck-bunny_trailer.webm .

Let me show you some differences i recognized.

[1] Its not playing in vlc (video ends before its started - blank screen), but that's not my main concern. out

[2] As you can see here a preview image is not generated (a standard android gallery) WhatsApp Image 2020-10-16 at 20 20 16

[3] And i can't share it with WhatsApp, it says "The file format is not supported", which is not true because the "bunny" test file is working fine: WhatsApp Image 2020-10-16 at 20 21 53

My users should be able to share the generated webm anywhere, so thats the reason why i'm here. :)

I know, this might be an not so important issue, but maybe somebody of you can point me in the right direction.


Is there a tool to make an 1:1 comparison with two webm files? (not only exifdata)

guest271314 commented 3 years ago

[1] Its not playing in vlc (video ends before its started - blank screen), but that's not my main concern.

Am not sure which specific decoders VLC uses. Have you filed a VLC bug?

[2] As you can see here a preview image is not generated (a standard android gallery)

Is that an Android bug, or a bug specific to the hardware of the device used for testing, not a webm-writer bug?

[3] And i can't share it with WhatsApp, it says "The file format is not supported", which is not true because the "bunny" test file is working fine:

I have not tried WhatsApp. Again, is that a WhatsApp bug?

Would suggest filing bug reports for each of the software and, or hardware used which produces the output described.

Is there a tool to make an 1:1 comparison with two webm files? (not only exifdata)

You can try mkvmerge -J test.webm from MKVToolNix https://gitlab.com/mbunkus/mkvtoolnix; ffprobe https://trac.ffmpeg.org/wiki/FFprobeTips; and converting the WebM file to XML representation https://github.com/vi/mkvparse.

thenickdude commented 3 years ago

You can dump the structure of a WebM using mkvinfo from MKVToolnix:

https://www.matroska.org/downloads/mkvtoolnix.html

mkvinfo --verbose --verbose --verbose --verbose --verbose test.webm
+ EBML head at 0
|+ EBML version: 1 at 8
|+ EBML read version: 1 at 12
|+ Maximum EBML ID length: 4 at 16
|+ Maximum EBML size length: 8 at 20
|+ Document type: webm at 24
|+ Document type version: 2 at 31
|+ Document type read version: 2 at 35
+ Segment: size unknown at 39
|+ Seek head at 44
| + Seek entry at 52
|  + Seek ID: 0x1c 0x53 0xbb 0x6b (KaxCues) at 58
|  + Seek position: 2424928 at 65
| + Seek entry at 73
|  + Seek ID: 0x15 0x49 0xa9 0x66 (KaxInfo) at 79
|  + Seek position: 71 at 86
| + Seek entry at 94
|  + Seek ID: 0x16 0x54 0xae 0x6b (KaxTracks) at 100
|  + Seek position: 131 at 107
|+ Segment information at 115
| + Timestamp scale: 1000000 at 123
| + Multiplexing application: webm-writer-js at 130
| + Writing application: webm-writer-js at 147
| + Duration: 00:00:04.000000000 at 164
|+ Tracks at 175
| + Track at 183
|  + Track number: 1 (track ID for mkvmerge & mkvextract: 0) at 188
|  + Track UID: 1 at 191
|  + Lacing flag: 0 at 195
|  + Language: und at 198
|  + Codec ID: V_VP8 at 205
|  + Codec name: VP8 at 212
|  + Track type: video at 219
|  + Video track at 222
|   + Pixel width: 1680 at 227
|   + Pixel height: 882 at 231
|+ Cluster at 235
| + Cluster timestamp: 00:00:00.000000000 at 243
| + Simple block: key, track number 1, 1 frame(s), timestamp 00:00:00.000000000 at 246
|  + Frame with size 604948 at 255
| + Simple block: key, track number 1, 1 frame(s), timestamp 00:00:01.000000000 at 605203
|  + Frame with size 606378 at 605212
| + Simple block: key, track number 1, 1 frame(s), timestamp 00:00:02.000000000 at 1211590
|  + Frame with size 606682 at 1211599
| + Simple block: key, track number 1, 1 frame(s), timestamp 00:00:03.000000000 at 1818281
|  + Frame with size 606682 at 1818290
|+ Cues at 2424972
| + Cue point at 2424980
|  + Cue time: 00:00:00.000000000 at 2424985
|  + Cue track positions at 2424988
|   + Cue track: 1 at 2424993
|   + Cue cluster position: 191 at 2424996
mkvinfo --verbose --verbose --verbose --verbose big-buck-bunny_trailer.webm
+ EBML head at 0
|+ EBML version: 1 at 5
|+ EBML read version: 1 at 9
|+ Maximum EBML ID length: 4 at 13
|+ Maximum EBML size length: 8 at 17
|+ Document type: webm at 21
|+ EBML void: size 2 at 28
|+ Document type version: 1 at 32
|+ Document type read version: 1 at 36
+ Segment: size 2165127 at 40
|+ Seek head at 48
| + Seek entry at 53
|  + Seek ID: 0x15 0x49 0xa9 0x66 (KaxInfo) at 56
|  + Seek position: 64 at 63
| + Seek entry at 67
|  + Seek ID: 0x16 0x54 0xae 0x6b (KaxTracks) at 70
|  + Seek position: 172 at 77
| + Seek entry at 81
|  + Seek ID: 0x11 0x4d 0x9b 0x74 (KaxSeekHead) at 84
|  + Seek position: 2165107 at 91
| + Seek entry at 97
|  + Seek ID: 0x1c 0x53 0xbb 0x6b (KaxCues) at 100
|  + Seek position: 3393 at 107
|+ Segment information at 112
| + Segment UID: 0x46 0xc6 0x9d 0x45 0xa1 0x85 0xa9 0x29 0x4d 0x3d 0x0a 0x2f 0x75 0x00 0x56 0xbd at 117
| + Timestamp scale: 1000000 at 136
| + Duration: 00:00:32.480000000 at 143
| + Date: Thu May 20 08:21:12 2010 UTC at 150
| + Multiplexing application: http://sourceforge.net/projects/yamka at 161
| + Writing application: Sorenson Squeeze at 201
|+ Tracks at 220
| + Track at 226
|  + Track number: 1 (track ID for mkvmerge & mkvextract: 0) at 228
|  + Track UID: 38308775201223106 at 231
|  + Track type: video at 241
|  + Default duration: 00:00:00.040000000 (25.000 frames/fields per second for a video track) at 244
|  + Timestamp scale: 1.0 at 252
|  + Codec ID: V_VP8 at 260
|  + Codec name: VP8 at 267
|  + Video track at 274
|   + Pixel width: 640 at 276
|   + Pixel height: 360 at 280
| + Track at 284
|  + Track number: 2 (track ID for mkvmerge & mkvextract: 1) at 287
|  + Track UID: 110618262945856186 at 290
|  + Track type: audio at 301
|  + Timestamp scale: 1.0 at 304
|  + Codec ID: A_VORBIS at 312
|  + Codec's private data: size 3097 at 322
|  + Codec name: Vorbis at 3423
|  + Audio track at 3433
|   + Sampling frequency: 44100.0 at 3435
|+ Cues at 3441
| + Cue point at 3447
|  + Cue time: 00:00:00.000000000 at 3449
|  + Cue track positions at 3452
|   + Cue track: 1 at 3454
|   + Cue cluster position: 3911 at 3457
| + Cue point at 3461
|  + Cue time: 00:00:00.600000000 at 3463
|  + Cue track positions at 3467
|   + Cue track: 1 at 3469
|   + Cue cluster position: 3911 at 3472
|   + Cue block number: 42 at 3476
| + Cue point at 3480
|  + Cue time: 00:00:03.520000000 at 3482
|  + Cue track positions at 3486
|   + Cue track: 1 at 3488
|   + Cue cluster position: 3911 at 3491
|   + Cue block number: 241 at 3495
| + Cue point at 3499
|  + Cue time: 00:00:07.120000000 at 3501
|  + Cue track positions at 3505
|   + Cue track: 1 at 3507
|   + Cue cluster position: 3911 at 3510
|   + Cue block number: 486 at 3514
| + Cue point at 3519
|  + Cue time: 00:00:09.080000000 at 3521
|  + Cue track positions at 3525
|   + Cue track: 1 at 3527
|   + Cue cluster position: 3911 at 3530
|   + Cue block number: 629 at 3534
| + Cue point at 3539
|  + Cue time: 00:00:11.200000000 at 3541
|  + Cue track positions at 3545
|   + Cue track: 1 at 3547
|   + Cue cluster position: 3911 at 3550
|   + Cue block number: 774 at 3554
| + Cue point at 3559
|  + Cue time: 00:00:13.200000000 at 3561
|  + Cue track positions at 3565
|   + Cue track: 1 at 3567
|   + Cue cluster position: 3911 at 3570
|   + Cue block number: 919 at 3574
| + Cue point at 3579
|  + Cue time: 00:00:13.880000000 at 3581
|  + Cue track positions at 3585
|   + Cue track: 1 at 3587
|   + Cue cluster position: 3911 at 3590
|   + Cue block number: 965 at 3594
| + Cue point at 3599
|  + Cue time: 00:00:15.000000000 at 3601
|  + Cue track positions at 3605
|   + Cue track: 1 at 3607
|   + Cue cluster position: 3911 at 3610
|   + Cue block number: 1057 at 3614
| + Cue point at 3619
|  + Cue time: 00:00:16.000000000 at 3621
|  + Cue track positions at 3625
|   + Cue track: 1 at 3627
|   + Cue cluster position: 3911 at 3630
|   + Cue block number: 1125 at 3634
| + Cue point at 3639
|  + Cue time: 00:00:16.600000000 at 3641
|  + Cue track positions at 3645
|   + Cue track: 1 at 3647
|   + Cue cluster position: 3911 at 3650
|   + Cue block number: 1166 at 3654
| + Cue point at 3659
|  + Cue time: 00:00:18.640000000 at 3661
|  + Cue track positions at 3665
|   + Cue track: 1 at 3667
|   + Cue cluster position: 3911 at 3670
|   + Cue block number: 1313 at 3674
| + Cue point at 3679
|  + Cue time: 00:00:18.880000000 at 3681
|  + Cue track positions at 3685
|   + Cue track: 1 at 3687
|   + Cue cluster position: 3911 at 3690
|   + Cue block number: 1334 at 3694
| + Cue point at 3699
|  + Cue time: 00:00:19.920000000 at 3701
|  + Cue track positions at 3705
|   + Cue track: 1 at 3707
|   + Cue cluster position: 3911 at 3710
|   + Cue block number: 1411 at 3714
| + Cue point at 3719
|  + Cue time: 00:00:20.880000000 at 3721
|  + Cue track positions at 3725
|   + Cue track: 1 at 3727
|   + Cue cluster position: 3911 at 3730
|   + Cue block number: 1476 at 3734
| + Cue point at 3739
|  + Cue time: 00:00:20.960000000 at 3741
|  + Cue track positions at 3745
|   + Cue track: 1 at 3747
|   + Cue cluster position: 3911 at 3750
|   + Cue block number: 1482 at 3754
| + Cue point at 3759
|  + Cue time: 00:00:22.000000000 at 3761
|  + Cue track positions at 3765
|   + Cue track: 1 at 3767
|   + Cue cluster position: 3911 at 3770
|   + Cue block number: 1559 at 3774
| + Cue point at 3779
|  + Cue time: 00:00:22.920000000 at 3781
|  + Cue track positions at 3785
|   + Cue track: 1 at 3787
|   + Cue cluster position: 3911 at 3790
|   + Cue block number: 1628 at 3794
| + Cue point at 3799
|  + Cue time: 00:00:24.920000000 at 3801
|  + Cue track positions at 3805
|   + Cue track: 1 at 3807
|   + Cue cluster position: 3911 at 3810
|   + Cue block number: 1765 at 3814
| + Cue point at 3819
|  + Cue time: 00:00:26.000000000 at 3821
|  + Cue track positions at 3825
|   + Cue track: 1 at 3827
|   + Cue cluster position: 3911 at 3830
|   + Cue block number: 1838 at 3834
| + Cue point at 3839
|  + Cue time: 00:00:26.680000000 at 3841
|  + Cue track positions at 3845
|   + Cue track: 1 at 3847
|   + Cue cluster position: 3911 at 3850
|   + Cue block number: 1884 at 3854
| + Cue point at 3859
|  + Cue time: 00:00:26.800000000 at 3861
|  + Cue track positions at 3865
|   + Cue track: 1 at 3867
|   + Cue cluster position: 3911 at 3870
|   + Cue block number: 1892 at 3874
| + Cue point at 3879
|  + Cue time: 00:00:29.960000000 at 3881
|  + Cue track positions at 3885
|   + Cue track: 1 at 3887
|   + Cue cluster position: 3911 at 3890
|   + Cue block number: 2114 at 3894
| + Cue point at 3899
|  + Cue time: 00:00:30.160000000 at 3901
|  + Cue track positions at 3905
|   + Cue track: 1 at 3907
|   + Cue cluster position: 3911 at 3910
|   + Cue block number: 2130 at 3914
| + Cue point at 3919
|  + Cue time: 00:00:30.240000000 at 3921
|  + Cue track positions at 3925
|   + Cue track: 1 at 3927
|   + Cue cluster position: 3911 at 3930
|   + Cue block number: 2141 at 3934
| + Cue point at 3939
|  + Cue time: 00:00:32.320000000 at 3941
|  + Cue track positions at 3945
|   + Cue track: 1 at 3947
|   + Cue cluster position: 3911 at 3950
|   + Cue block number: 2296 at 3954
|+ Cluster at 3959
| + Cluster timestamp: 00:00:00.000000000 at 3967
| + Cluster position: 3911 at 3970
| + Simple block: key, track number 1, 1 frame(s), timestamp 00:00:00.000000000 at 3974
|  + Frame with size 431 at 3981
...
|+ Seek head at 2165155
| + Seek entry at 2165160
|  + Seek ID: 0x1f 0x43 0xb6 0x75 (KaxCluster) at 2165163
|  + Seek position: 3911 at 2165170
mst2020 commented 3 years ago

@guest271314 thanks for your answer. in my opinion, other webm (all V_VP8) are working fine, it is a problem with the generated webm.

@thenickdude thanks! mkvinfo helped me to find a suspicious information.

My tested files have all set the root segment size, the webm from this writer not:

Segment: size unknown at 39 (webm-writer) Segment: size 2165127 at 40 (big-bunny) Segment: size 233884 at 38 (http://antimatter15.com/whammy/clock.html)

webm-writer sets this to "-1" - "unbounded": https://github.com/thenickdude/webm-writer-js/blob/516891de216942e5cd3a54d07bd0d2a39a47875a/src/WebMWriter.js#L534

Is there a way i can calculate this value correctly? (or for testing: calculate it by myself?)

mst2020 commented 3 years ago

So, i tested it with setting the segment size to an estimated value (filesize - 50) and it is working in vlc and whatsapp. (not perfect, but that's because of the incorrect size)

Setting https://github.com/thenickdude/webm-writer-js/blob/516891de216942e5cd3a54d07bd0d2a39a47875a/src/WebMWriter.js#L534 to another value results in a wrong (calculated) size - i guess that's why it is "disabled"?

I just matched the id and set another value: https://github.com/thenickdude/webm-writer-js/blob/516891de216942e5cd3a54d07bd0d2a39a47875a/src/WebMWriter.js#L196

Is there a way to update the segment size before finish writing?

thenickdude commented 3 years ago

Thanks for that testing, I'll take a look

thenickdude commented 3 years ago

It looks like an unbounded size for the Segment node conforms fine to the Matroska specification (since it's the only way to create a streaming video of unbounded length), and they even have one in their test set which uses that feature, and it plays fine in VLC:

https://github.com/Matroska-Org/matroska-test-files/blob/master/test_files/test4.mkv

And the WebM Byte Stream spec also explicitly allows Segments of unknown size:

https://www.w3.org/TR/mse-byte-stream-format-webm/#webm-init-segments

I wonder what's going on here exactly. Oh well, it's simple enough for my encoder to write the segment length in.

thenickdude commented 3 years ago

Can you test this commit for me? https://github.com/thenickdude/webm-writer-js/commit/bbcd90f964a5e084080c73f2c5e046f48e7fd0e3

mst2020 commented 3 years ago

The commit works fine with:

but not in vlc (3.0.9.2, ubuntu 20.04) ... its the same behavior like before. so i guess they have a really shitty webm integration. :) funny thing, if i reduce the size to something "random" (e.g. blobBuffer.pos - ebmlSegment.dataOffset - 28), vlc is opening the file and shows at least 3 (of 4) frames (the other frame is out of the size bound i guess) ... ... with "-27" vlc remains black. 🙄

so there is something else different in the generated webm, but i didn't get to know what. i tested removing the cues and seek segments (whammy doesn't has those), but that doesn't have changed anything. so my ideas where to look are exhausted.

having "all" the messengers (in my limited test case) working with it is a huge improvement and setting the segment size isn't a "workaround". so in my opinion its fine to apply the commit to fix it at least for two billion people (whatsapp user ;)).

maybe i'll file a bug-report for vlc ... 🙄

thenickdude commented 3 years ago

Is VLC unhappy with your extremely low FPS/total frame count? Maybe it expects to be able to completely fill a buffer full of frames before it starts playing the video. Try doubling or tripling up your frames and see what happens.

mst2020 commented 3 years ago

@thenickdude good point.

vlc struggles with the amount of frames, the fps and the duration in general. as a workaround, and because i'm showing a loop, i could show the frames 3 times to make the file longer. (but that's not interesting here, maybe some helpful information for the vlc guys.)

At least the whatsapp problem is solved (&maybe some other tools), i'm happy with that. :+1: 😀

Many thanks to you!

guest271314 commented 3 years ago

This is a VLC bug, and not limited to webm-writer implmentation.

I recorded a video at Chromium using this code https://plnkr.co/edit/oYRSCpNQAL92Yb5o?preview which provides a means to record precise amount of frames, created as a workaround for https://bugs.chromium.org/p/chromium/issues/detail?id=1047984.

$ vlc 32326038-b8ae-4a45-87eb-7ecaddb122b8.webm
VLC media player 3.0.9.2 Vetinari (revision 3.0.9.2-0-gd4c1aefe4d)
[000055a327c3f690] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
qt5ct: using qt5ct plugin
qt5ct: D-Bus global menu: no
qt5ct: D-Bus system tray: yes
libva info: VA-API version 1.7.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/radeonsi_drv_video.so
libva info: Found init function __vaDriverInit_1_7
libva info: va_openDriver() returns 0
mesa: for the --simplifycfg-sink-common option: may only occur zero or one times!
mesa: for the --global-isel-abort option: may only occur zero or one times!
mesa: for the --amdgpu-atomic-optimizations option: may only occur zero or one times!
[00007ff530001fc0] glconv_vaapi_x11 gl error: vaDeriveImage: operation failed
[00007ff4d0000cb0] main video output error: video output creation failed
[00007ff4e0c11770] main decoder error: failed to create video output
[00007ff4e0c11770] main decoder error: buffer deadlock prevented
libva info: VA-API version 1.7.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/radeonsi_drv_video.so
libva info: Found init function __vaDriverInit_1_7
libva info: va_openDriver() returns 0
[00007ff4c40014f0] glconv_vaapi_x11 gl error: vaDeriveImage: operation failed
[00007ff4e0c06b20] main video output error: video output creation failed
[00007ff528c22210] main decoder error: failed to create video output
[00007ff528c22210] main decoder error: buffer deadlock prevented
libva info: VA-API version 1.7.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/radeonsi_drv_video.so
libva info: Found init function __vaDriverInit_1_7
libva info: va_openDriver() returns 0
[00007ff4dc001a90] glconv_vaapi_x11 gl error: vaDeriveImage: operation failed
[00007ff528000cb0] main video output error: video output creation failed
[00007ff530896350] main decoder error: failed to create video output
[00007ff530896350] main decoder error: buffer deadlock prevented

There are only two (2) frames in the video.

Chromium lists duration of the video as 15 seconds. Firefox, which implements HTMLMediaElement.seekToNextFrame() correctly lists duration as 30 seconds.

Once comparisons are being made between video decoders and players it is possible to find multiple inconsistencies.

For a player would suggest to use mpv, or suggest that application to your users. In the meantime, not only does VLC have a bug, but so does Chromium re displaying correct duration of video.

guest271314 commented 3 years ago

Here is the video that I recorded. Try for yourself at Chromium and Firefox 32326038-b8ae-4a45-87eb-7ecaddb122b8.webm.zip, an illustration of the range of video decoders in the field.

thenickdude commented 3 years ago

I've now published this fix on NPM as 0.3.1