HTTP byte range yields a corrupt audio file? - file

when i open a .m4a or .mp3 file using chrome (or in VLC "open new stream), and skip to a certain time mark, it starts streaming the audio right at that time mark, which means that it downloads a chunk from the audio file starting at that position.
when i check network under chrome dev tools after i click somewhere in the audio player, and copy the cURL request, it contains a range http header, for example:
-H "Range: bytes=26500000-30000000"
when i run that cURL command in the terminal, the output is a corrupt audio file. if i try to convert it using ffmpeg, it logs:
[mov,mp4,m4a,3gp,3g2,mj2 # 00000164d5a3ab40] moov atom not found
the only exception is when i request a byte range starting from 0 (and ending at 300000+) in which case the output file can play.
from what i understand, the headers of the audio file are not downloaded when the byte range is somewhere in the middle or ending of the file.
i tried specifying two ranges, as follows
-H "Range: bytes=0-300000,2000000-4000000"
but the output file is corrupt nevertheless.
how does chrome/vlc deal with this situation, and how can i replicate it? what is the right way to download an audio chunk from a large audio file? i am guessing i would have to make consecutive http requests to build a proper, non-corrupt file, it seems that it is what chrome does.
UPDATE
a "temporary fix" i found to the problem that you might find useful is to use launch VLC through command with a hidden interface, load the audio stream (in this case the audio file url) and transcode the audio to a local file while assigning a start and stop time. an example, with a random podcast:
vlc -Idummy --play-and-exit --sout "#transcode{acodec=s16l,channels=2,samplerate=44100}:std{access=file,mux=wav,dst=C:\audio\output.wav}" --start-time=600 --stop-time=630 "http://traffic.libsyn.com/preview/worldofhardwarestartups/World_of_Hardware_Startups_Podcast_EP01_-_AIR_Ready.mp3"
however, the original issue is still unsolved.

Related

Merge two videos with different HTTP Range header bytes

I want to save 10 seconds from any part of a video by using its URL (without downloading it completely).
the server supports the Range header and it's possible to get specific byte ranges, the video is ok when I save it with something like Range: bytes=0-102400 but when I change the start byte and save a video with Range: bytes=307200-614400 it's no longer playable.
I know maybe it lacks a MIME/header type that should be at the beginning of a file, but the first bytes are not in this response to specify the correct format of the file.
so I saved the video from 0-102400, which is ok and playable, and wanted to get that specific range and somehow append it after the first file to have both a correct file header (less than 1 sec) and that middle part of the video.
first.webm Range: bytes=0-102400 (valid playable file)
middle.webm Range: bytes=307200-614400 (not playable file)
I tried to merge them using this command recommended by this answer
ffmpeg -f concat -i list.txt -c copy merged.webm
logs:
[matroska,webm # 000002143c3e77c0] File ended prematurely00 bitrate=3752.0kbits/s speed=N/A
[matroska,webm # 000002143c429e40] Format matroska,webm detected only with low score of 1, misdetection possible!
[matroska,webm # 000002143c429e40] EBML header parsing failed
[concat # 000002143c3dda80] Impossible to open 'middle.webm'
list.txt: Invalid data found when processing input
frame= 42 fps=0.0 q=-1.0 Lsize= 10kB time=00:00:01.64 bitrate= 48.7kbits/s speed= 231x
video:9kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 8.500000%
generated video only shows the first video (which was already playable before merging) and ends.
I inspired this idea from this answer and don't want to download the complete video. If I can't merge them is it possible and how to write a MIME/header for the middle.webm manually to make it a valid playable video?

Writing matroska to an append only stream

I need to write a matroška video file to a stream that only supports an append operation (not network streaming, output is a single MKV file for offline playback). Right now I'm using ffmpeg's libavformat to do the muxing, but the resulting video file is not seekable (in a player) at all.
Going through the matroška specs, I figured out a way to create a seekable (in a player) file work with only one (file) seek operation:
SeekHead 1 (without clusters)
...
Clusters
Cues
SeekHead 2 (only clusters)
After the file is written I need to go back to SeekHead 1 and update it with positions of SeekHead 2 and Cues.
My output files can easily get to tens of gigabytes, so buffering the whole thing in memory is not an option.
Is there really no way to create the MKV without seeking in the output file?

Reading in the output of a program, saving it as a string, and using that string in the original program

I am using trying to get specific information from a group of MP3 files, currently I am in the main cygwin64 that holds MP3 files and a .C file which simply contains
FILE * fp;
It contains that single line of code because when that line of code is in place and I type and run "thing.c" in the cygwin command line it outputs what seems the be the information of the contents of the folder. For example it outputs,
home: sticky, directory
lib: directory
sbin: directory
setup-x86_64.exe: PE32+ executable (GUI) x86-64 (stripped to external PDB), for MS Windows
song.mp3: Audio file with ID3 version 2.3.0, contains: MPEG ADTS, layer III, v1, 128 kbps, 44.1 kHz, JntStereo
song1.mp3: Audio file with ID3 version 2.3.0, contains: MPEG ADTS, layer III, v1, 128 kbps, 44.1 kHz, JntStereo
thing.c: ASCII text, with CRLF line terminators
thing.txt: empty
What I want to do is be able to pull that output into a string that I can then use in my C file and alter and then re print out the new altered information. However I'm not sure where the output really is coming from or how I might be able to get it or save the output as a .txt file or back into a C file.
Any advice is appreciated Thanks!
This file is not really a C file at all. Because you're in Cygwin, you're likely operating on a case-insensitive filesystem (NTFS). As such, Cygwin's file command is running when you run the .c file. The way you've attempted to declare a variable (apparently) just so happens to be doing a 'file * fp' command. I'm sure you're getting fp: Cannot open "fp" or something similar after the rest of your output.
This is not anything C-related at all but is just being interpreted as a script by your shell.
It sounds like you have a lot to learn if you want to do this in C. More likely, you can probably write a shell script to accomplish what you want. While I've never used it, mp3info (https://github.com/jaalto/cygwin-package--mp3info) exists for pulling tag information from MP3 files. You could possibly get the exact information you want from that, or pipe the output into sed, awk, or a number of other tools.

FFmpeg decoding .mp4 video file

I'm working on a project that needs to open .mp4 file format, read it's frames 1 by 1, decode them and encode them with better type of lossless compression and save them into a file.
Please correct me if i'm wrong with order of doing things, because i'm not 100% sure how this particular thing should be done. From my understanding it should go like this:
1. Open input .mp4 file
2. Find stream info -> find video stream index
3. Copy codec pointer of found video stream index into AVCodecContext type pointer
4. Find decoder -> allocate codec context -> open codec
5. Read frame by frame -> decode the frame -> encode the frame -> save it into a file
So far i encountered couple of problems. For example, if i want to save a frame using av_interleaved_write_frame() function, i can't open input .mp4 file using avformat_open_input() since it's gonna populate filename part of the AVFormatContext structure with input file name and therefore i can't "write" into that file. I've tried different solution using av_guess_format() but when i dump format using dump_format() i get nothing so i can't find stream information about which codec is it using.
So if anyone have any suggestions, i would really appreciate them. Thank you in advance.
See the "detailed description" in the muxing docs. You:
set ctx->oformat using av_guess_format
set ctx->pb using avio_open2
call avformat_new_stream for each stream in the output file. If you're re-encoding, this is by adding each stream of the input file into the output file.
call avformat_write_header
call av_interleaved_write_frame in a loop
call av_write_trailer
close the file (avio_close) and clear up all allocated memory
You can convert a video to a sequence of losses images with:
ffmpeg -i video.mp4 image-%05d.png
and then from a series of images back to a video with:
ffmpeg -i image-%05d.png video.mp4
The functionality is also available via wrappers.
You can see a similar question at: Extracting frames from MP4/FLV?

processing .raw file image with ffmpeg api or C code

I am trying to process a .raw image file captured using vrl2, it's a h264 encoded image with yuv422 color space from a Logitech c920 webcam, dcraw is not working for me however from my previous question this command is working fine with low performance (a 32kb jpg image however using opencv capture I get a 900kb image for the same 640x480 resolution):
ffmpeg -f rawvideo -s 640x480 -pix_fmt yuyv422 -i frame-1.raw
frame-1.jpg
I need a code written in C or the ffmpeg api/OpenCV etc .. to do the same as this command,I don't want to use QProcess in Qt(I am working on a server using Qt where I am trying to send the raw file from a Raspberry PI to the server and process it their), dcraw output is a corrupted image.
http://ffmpeg.org/doxygen/trunk/examples.html
There should be some api samples in there that show how to get the image out with that specific encoding.
When interacting with a RAW file, I have also used IrfanView. If you know the headersize of the file and the width and the height and the bits per pixel per color, you can see what it looks like quickly that way.
EDIT: I tried using Irfanview with your RAW, and I got something close, but not quite. The coloring was always off. I don't think it can handle that particular encoding of a RAW file right now.

Resources