WhatsApp video as Gif sharing on Android programat

2019-04-07 13:20发布

问题:

How can i convert a mp4 video file to a WhatsApp gif file (it's simple showed as gif inside app UI but internally is a specific mp4 format) to be use in android share intent, being recognized as this type of media by whatsapp chat app???

I search a lot but i can't find any information from WhatsApp docs (they don't have this kind of doc anyway) or any dev with the same problem as i.

WHAT I HAVE:

I have discovered that at beginning of whatsapp "gif" mp4 files is present a loop value if you read they on hex editor, all files have this. Remove this value make whatsapp receive as regular video (not sharing as gif).

How can i add this value using ffmpeg encoding? (editing my mp4 files manually with this value corrupt the files, maybe i have to fix some mp4 header index that i don't know yet...)


FIRST 80 BYTES in hexadecimal (from beginning to start of "moov" atom from mp4 structure):

00 00 00 1C 66 74 79 70 6D 70 34 32 00 00 00 01 6D 70 34 31 6D 70 34 32 69 73 6F 6D 00 00 00 18 62 65 61 6D 01 00 00 00 01 00 00 00 00 00 00 00 05 00 00 00 00 00 00 0C 6C 6F 6F 70 00 00 00 00 00 00 00 08 77 69 64 65 00 00 04 9F 6D 6F 6F 76

A short mp4 file generated by WhatsApp that internally (at app) was showed as a Gif (with different UI):

https://www.dropbox.com/s/kpynmx1bg3z76lz/VID-20171024-WA0009.mp4?dl=0

回答1:

"...The problem is that I can't edit another MP4 file to add this atom without corrupt the file.

Test this small_VC1edit.mp4 in WhatsApp. If it does what you want then read on...

To make a playable MP4 :

Using original small.mp4 as an editing example (download file and open with a hex editor).

1) In a blank byte array, add the first 72 bytes of the shown WhatsApp-style MP4 header.

00 00 00 1C 66 74 79 70 6D 70 34 32 00 00 00 01 6D 70 34 31 6D 70 34 32 69 73 6F 6D 00 00 00 18 62 65 61 6D 01 00 00 00 01 00 00 00 00 00 00 00 05 00 00 00 00 00 00 0C 6C 6F 6F 70 00 00 00 00 00 00 00 08 77 69 64 65

You've shown 80 bytes but the last 8 bytes are not needed yet (also four of those eight byte's values must be different for your output file).

2) Calculate the deltas.

  • Note the (new) WhatsApp header is 72 bytes (before moov atom).

  • Note the (original) Small.mp4 has 160 bytes of header (before moov atom).

So just use this logic (a or b):

  • a) If WhatsApp header is bigger than input MP4 :
    delta = ( WhatsApp_header - input_MP4_header)

  • b) If input MP4 header is bigger than WhatsApp :
    delta = ( input_MP4_header - WhatsApp_header )

So for the input small.mp4 which has 160 header bytes (is followed next by 4 bytes of moov's SIZE (as 00 00 0D 83) and then follows another 4 bytes now of moov's NAME (as 6D 6F 6F 76 or utf-8 text of "moov").

We can say : 160 MP4 bytes - 72 WhatsApp bytes = Delta of 88.

If you delete these original 160 bytes and replace them with the shorter 72 WhatsApp bytes, they'll be 88 less bytes which must now be accounted for in the another section of MOOV data. That section is the STCO atom.

3) Update the STCO atom with new offsets:

In small.mp4 the STCO atom begins at offset 1579 (as 73 74 63 6F). The previous 4 bytes (offsets: 1575 to 1578) are stco's SIZE bytes (as 00 00 00 B8) which is decimal value 184. This total SIZE of bytes length includes accounting for those 4 SIZE bytes too.

Skip 12 bytes from the starting byte 73 of the stco's NAME bytes 73 74 63... so skip these:

73 74 63 6F 00 00 00 00 00 00 00 2A

Now you reach point to sequentially update every 32-bit integer (4 bytes) of offsets with the new delta value. But how many offsets to update?

atomEditTotal = ( (stco_SIZE - 16) / 4); //gives 42 //PS: Minus by 16 is to trim off non-offset bytes.

So there are 42 entries to edit. Our Delta as 88 so for each integer we read value, minus it by 88, then write it back new value at same place, repeat another 41 times (using While loop with an if condition to break; the loop).

For testing, given a corrupt file, if you edit the first entry it should be enough to show frame 1 of video (if non-audio file).

PS: After editing the STCO offsets of small.mp4, just delete its starting 160 bytes and join/concat those remaining MP4 bytes to the back/end of the 72 byte WhatsApp header. Save array as new file and test.