Get Opus Headers for Ogg - ios

I have this example of getting the initial header information from Vorbis for Ogg Stream:
ogg_packet header;
ogg_packet header_comm;
ogg_packet header_code;
vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
How can I get this header information from Opus with libopus?
There's some information HERE, but I can't figure out how work with it.

Ogg Opus has only two header packets: the ID header and comment header. See the specification for details on their contents.
If you are reading an Ogg Opus file with the opusfile library, it processes the packets for you (including the header packets). The various functions that you linked to are used to get information from the headers that were processed.
If you are writing an Ogg Opus file, you can use the libopusenc library and it will take care of writing the headers for you. As of version 0.2, the opusenc program in the opus-tools package uses libopusenc. If for some reason you want to format and write the packets yourself using the ogg library directly, you could take a look at the older 0.1.10 version of opusenc, when it did this itself; look for the comment /* Write header */ in opusenc.c and the call to opus_header_to_packet() to format the ID header.

Related

How to Extract Audio from WebM File

I just want to get a audio file(opus codec used) only in webm file.
I try to search what is webm format, how to parse, but I cant get info well.
I check that webm format is from mkv, then should I check the mkv first?
there is just one github code, but I cant find way how parse the audio from webm.
https://github.com/webmproject/libwebm/tree/master/webm_parser
You're really going to want the MKVToolNix. These include the tool mkvextract in another answer.
The MKVToolNix is actually a series of tools (mkvmerge, mkvinfo, mkvextract, mkvpropedit). First you asked how to parse the info. You can find the details using:
mkvinfo file.webm
mkvinfo file.webm -a
The first command will parse the overall structure. The second gives the detail of each frame. Use the --help switch if you want all commands.
To extract the audio, do
mkvextract file.webm tracks X:newfile.opus
Where X is the track number that you've identified as wanted from mkvinfo previously. Webm and MKV can have multiple tracks. "newfile.opus" is the new file that you want to create, choose the name you want.
There is also a mkvtoolnix gui, but I've never used that.
mkvextract can extract audio for you, and I recommend having a look at the mkvtoolsnix source code.
For example, you can extract audio from a WebM file into an Ogg Opus file like this:
$ mkvextract ~/audio/bubbles.webm tracks 0:audio.opus
Extracting track 0 with the CodecID 'A_OPUS' to the file 'audio.opus'. Container format: Ogg (Opus in Ogg)
Progress: 100%

GZip stream compression with Delphi (optionally with tar)

I am searching and searching since hours to create a valid .tar.gz file using streams in Delphi 10.
I was able to solve the tarball part using LibTar, which works well.
After some searching I also found examples to decompress gzip data using just System.ZLib. The secret lies in the WindowBits parameter:
// 31 bit wide window = gzip only mode
DecompStream:= TZDecompressionStream.Create(SourceStream, 15 + 16);
TarStream:= TTarArchive.Create(DecompStream);
TarStream.Reset;
while TarStream.FindNext(DirRec) do {...} TarStream.ReadFile(TargetStream);
Great! But is it really possible that System.ZLib is able to decompress gzip (I guess by just ignoring the gzip header by that +16?), but is not able to create such header by itself? Whatever I try, I only get a file that cannot be opened by 7zip or WinRar, because the header is missing.
Maybe it just can't work, because the gzip header contains a checksum, so it's not possible to write the header without knowing the following data. How to solve this? Edit: this is wrong, see comments: crc32 is in the trailer.
It seems, many others also have this problem - I found and tried multiple solutions to add this header, but nothing really worked and everything requires adding long units (not nice but acceptable) or even DLLs (not acceptable for me).
The secret lies in the WindowBits parameter - sounds familiar? :)
Believe it or not, compressing to gzip just works the same way! I couldn't find this anywhere using Google, or in the Embarcadero documentation/help. But have a look at this comment in the System.ZLib source of Delphi Tokyo:
Add 16 to windowBits to write a simple gzip header and
trailer around the compressed data instead of a zlib wrapper. The
gzip header will have no file name, no extra data, no comment, no
modification time (set to zero), no header crc, and the operating
system will be set to 255 (unknown).
It works:
TargetStream:= TFileStream.Create(TargetFilename, fmCreate);
CompressStream:= TZCompressionStream.Create(TargetStream, zcDefault, 15 + 16);
TarStream:= TTarWriter.Create(CompressStream);
TarStream.AddStream(SourceStream1, SourceFilename1, Now);
TarStream.AddString(SourceString2, SourceFilename2, Now);

How do I use the CLI interface of FFMpeg from a static build?

I have added this (https://github.com/kewlbear/FFmpeg-iOS-build-script) version of ffmpeg to my project. I can't see the entry point to the library in the headers included.
How do I get access to the same text command based system that the stand alone application has, or an equivalent?
I would also be happy if someone could point me towards documentation that allows you to use FFmpeg without the command line interface.
This is what I am trying to execute (I have it working on windows and android using the CLI version of ffmpeg)
ffmpeg -framerate 30 -i snap%03d.jpg -itsoffset 00:00:03.23333 -itsoffset 00:00:05 -i soundEffect.WAV -c:v libx264 -vf fps=30 -pix_fmt yuv420p result.mp4
Actually you can build ffmpeg library including the ffmpeg binary's code (ffmpeg.c). Only thing to care about is to rename the function main(int argc, char **argv), for example, to ffmpeg_main(int argc, char **argv) - then you can call it with arguments just like you're executing ffmpeg binary. Note that argv[0] should contain program name, just "ffmpeg" should work.
The same approach was used in the library VideoKit for Android.
To do what you want, you have to use your compiled FFmpeg library in your code.
What you are looking for is exactly the code providing by FFmpeg documentation libavformat/output-example.c (that mean AVFormat and AVCodec FFmpeg's libraries in general).
Stackoverflow is not a "do it for me please" platform. So I prefer explaining here what you have to do, and I will try to be precise and to answer all your questions.
I assume that you already know how to link your compiled (static or shared) library to your Xcode project, this is not the topic here.
So, let's talk about this code. It creates a video (containing video stream and audio stream randomly generated) based on a duration. You want to create a video based on a picture list and sound file. Perfect, there are only three main modifications you have to do:
The end condition is not reaching a duration, but reaching the end of your file list (In code there is already a #define STREAM_NB_FRAMES you can use to iterate over all you frames).
Replace the dummy void fill_yuv_image by your own method that load and decode image buffer from file.
Replace the dummy void write_audio_frame by your own method that load and decode the audio buffer from your file.
(you can find "how to load audio file content" example on documentation starting at line 271, easily adaptable for video content regarding documentation)
In this code, comparing to your CLI, you can figure out that:
const char *filename; in the main should be you output file "result.mp4".
#define STREAM_FRAME_RATE 25 (replace it by 30).
For MP4 generation, video frames will be encoded in H.264 by default (in this code, the GOP is 12). So no need to precise libx264.
#define STREAM_PIX_FMT PIX_FMT_YUV420P represents your desired yuv420p decoding format.
Now, with these official examples and related documentation, you can achieve what you desire. Be careful that there is some differences between FFmpeg's version in these examples and current FFmpeg's version. For example:
st = av_new_stream(oc, 1); // line 60
Could be replaced by:
st = avformat_new_stream(oc, NULL);
st->id = 1;
Or:
if (avcodec_open(c, codec) < 0) { // line 97
Could be replaced by:
if (avcodec_open2(c, codec, NULL) < 0) {
Or again:
dump_format(oc, 0, filename, 1); // line 483
Could be replaced by:
av_dump_format(oc, 0, filename, 1);
Or CODEC_ID_NONE by AV_CODEC_ID_NONE... etc.
Ask your questions, but you got all the keys! :)
MobileFFMpeg is an easy to use pod for the purpose. Instructions on how to use MobileFFMpeg at: https://stackoverflow.com/a/59325680/1466453
MobileFFMpeg gives a very simple method for translating ffmpeg commands to your IOS objective-c program.
Virtually all ffmpeg commands and switches are supported. However you have to get the pod with appropriate license. e.g min-gpl will not give you features of libiconv. libiconv is convered in vidoe, gpl and full-gpl licenses.
Please highlight if you have specific issues regarding use of MobileFFMpeg

System.Zip.TZipFile.ExtractZipFile throws error with certain files. Why?

When extracting a ZIP file with System.Zip.TZipFile:
System.Zip.TZipFile.ExtractZipFile('C:\test.zip', 'R:\_TEST\');
for a specific ZIP file I get this error message box:
Stream read error.
Why?
The zip file which to reproduce the error, base64 encoded:
UEsDBC0ACAAIAHyDiEcAAAAA//////////8WABQATmV1ZXMgVGV4dGRva3VtZW50LnR4dAEAEAAA AAAAAAAAAAIAAAAAAAAAAwBQSwcIAAAAAAIAAAAAAAAAAAAAAAAAAABQSwECLQstAAgACAB8g4hH AAAAAP//////////FgA4AAAAAAABAAAAAAAAAAAATmV1ZXMgVGV4dGRva3VtZW50LnR4dAEAEAAA AAAAAAAAAAIAAAAAAAAACgAgAAAAAAABABgA1LFkAs0x0QHUsWQCzTHRAdSxZALNMdEBUEsFBgAA AAABAAEAfAAAAGIAAAAAAA==
Go to http://www.motobit.com/util/base64-decoder-encoder.asp
Decode this to your local storage as test.zip (don't change the character set)
The MD5 of the decoded binary file must be:
7357193E8F27FE1FB5AF2B8B6AF1F24C
Reference: The structure of a PKZip file
by Florian Buchholz.
Your ZIP file is stored using the ZIP64 extended variant of the format. The Delphi ZIP code does not support ZIP64.
I deduced that the file was ZIP64 by looking at the local file header. The compressed and uncompressed size fields are both 0xffffffff. From the reference above:
Compressed size: if archive is in ZIP64 format, this filed is 0xffffffff and the length is stored in the extra field
Uncompressed size: if archive is in ZIP64 format, this filed is 0xffffffff and the length is stored in the extra field
For the library to support ZIP64 it needs to detect these conditions and read the 64 bit values out of the additional headers. The Delphi code does not and attempts to read 0xffffffff bytes that are not there.
You will need to find a different ZIP file library, one that supports ZIP64, in order to operate on such a ZIP file. Alternatively, you could side-step the problem if you could arrange that whatever creates the ZIP files uses the plain ZIP format.

DXGI_FORMAT in dds file

I am parsing DDS file to read its header data. I want to modify format of image, but it seems that header mentioned at this site does not specify where DXGI_FORMAT (internal format) is stored. Where I can I get internal format in file ?
Like DXGI_FORMAT_BC1_UNORM value is 71, but i did not find it in header

Resources