Prepending a header to a headerless .m4a file - metadata

I have some .m4a files that were captured from a radio broadcast stream. They are playable using mpd (an open source Music Playing Daemon for *nix), but iTunes won't open them (nor will several other music players that should be able to play .m4a files). When I looked at the file in hex format, and compared it to an .m4a file from iTunes, it appeared that the file from the broadcast stream did not have any header info.
So I figured I'd try prepending some header info to the file, to see if that would make it playable by these other players.
I've tried to read the technical doc about the .m4a file format to understand how the header is structured, but it's far too complex for me to follow (most of the doc is about the coding, which isn't pertinent to this). The header seems fairly simple, conceptually - I can see 4-character tags, variable length data, and there are presumably some length codes to allow these to be split apart. It doesn't seem to contain any significant data about the actual audio data (like its total length), making me hopeful that I might be able to get by by simply copying the header from an .m4a file and prepending it to these headerless files.
I'm unable, though, to manually parse (that is, reverse-engineer) the header in order to even experiment with this. Can someone describe how to identify a complete header at the front of a .m4a file?

Related

Can I upload already-encoded content to azure media services, instead of uploading a video and then encoding it? How?

I want to encode locally and upload to avoid spending money in encoding.
Is this allowed? I did not find any documentation on it.
When I simply uploaded a file to the storage, the media services account said it could not play it without the ISM file. I had to encode (was it re-encode? it was an mp4) the file I had uploaded - I want to avoid that.
Yes, absolutely allowed and encouraged for customers. Especially ones that have custom encoding requirements that we may not support.
You can upload an .ism file that you create along with your encoded files. It's a simple SMIL 2.0 format XML file that points to the source files used.
It's a bit hard to find searching the docs, but there is a section outlining the workflow here - https://learn.microsoft.com/en-us/azure/media-services/latest/encode-dynamic-packaging-concept#on-demand-streaming-workflow
There is also a .NET Sample showing how to do it here:
https://github.com/Azure-Samples/media-services-v3-dotnet/tree/main/Streaming/StreamExistingMp4
You can see the code line at 111 that shows how to generate the .ism file -
// Generate the Server manifest for streaming .ism file.
// This file is a simple SMIL 2.0 file format schema that includes references to the uploaded MP4 files in the XML.
var manifestsList = await AssetUtils.CreateServerManifestsAsync(client, config.ResourceGroup, config.AccountName, inputAsset, locator);

Writing MP4 tags for M4A or MP4 audio files

I have a strange problem with MP4 tagging.. I can figure out 2 styles of tags, one that works with mp3tag and tagscanner, another that works with MusicBee.. But I can't figure out one that universally works with all of those. So I write 2 sets of tags into the file...
and even this isn't enough.. Players like AIMP and Clementine still can't read MP4 files I tagged this way. I need to open mp3tag load my files and save them.. then it will write tags that those music players understand.. but I can't find good documentation anywhere.
Does anyone know what kind of tags I need to write to make all of them be able to read the tags? I tried to look mp4s that work in all of them and it is no use, I see tags like "Artist".. I already write a tag called "Artist".. I mean it looks like "Artist" in exif also, this is the tag that I wrote that MusicBee understands.
I use the AudioGenie Windows Library to write the tags. There are 2 different methods for writing a tag.. one is called an ISLT text frame (which I have no idea what that is) and requires an integer code as well as text when writing. Another is called an iTune text frame and requires a string frame ID as well as text.
I tried to shove MP3 ID3v2 tags in both of those as well, to see if that was what the third group of players that can't read my tags wanted. But that didn't work. I only tried this because I read somewhere that ID3v2 tags are widely used in MP4 files (it was only on one comment in stackoverflow that I read this, so I'm skeptical)
Could someone point me in the right direction?

Download Result of Source Destination (Web Audio API)

I'm building a tool to edit audio with the Web Audio API.
Here is where I'm stuck:
...
source
.connect(gainNode)
.connect(analyser)
.connect(analyser2)
.connect(audioCtx.destination);
};
What I've written (which ends with the code above) successfully allows the user to upload a file, apply effects, and listen to it on play(). How would I then allow the user to click a button to export the results to a WAV file?
I've tried several methods online that have not worked for my use case.
Please let me know if more code is needed. Thank you for taking a look!
If you want a WAV file, I think you have to do that yourself. WAV files are quite simple. In this case, you'll need to add either a ScriptProcessorNode or AudioWorkletNode just before the destination to capture all the audio and convert it to a WAV file that can be downloaded.
If a compressed file is ok, you can look into MediaRecorder to save the data for you.
I ended up solving this by writing an entirely different script to download the file using OfflineAudioContext.
My original script plays the audio with effects, and the second script downloads it with the same effects. Now to figure out why there is latency on the effects while using OfflineAudioContext.

Playlist file(m3u8) give another playlist file infinitely not giving any media file

I have a playlist file which give me another playlist file which also give me another playlist file, continously.
How can I play this playlist file? and Where can I found the source of video?
For example, I have a playlist file. That is
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=355670
http://slive.ytn.co.kr:1935/live/ylive_0624_1.sdp/playlist.m3u8?wowzasessionid=195968950
If I access to http://slive.ytn.co.kr:1935/live/ylive_0624_1.sdp/playlist.m3u8?wowzasessionid=195968950, it give me other playlist files.
#EXTM3U
#EXT-X-ALLOW-CACHE:NO
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:894
#EXTINF:11,
media_894.ts?wowzasessionid=195968950
#EXTINF:10,
media_895.ts?wowzasessionid=195968950
#EXTINF:11,
media_896.ts?wowzasessionid=195968950
If I access to the results, it also give me playlist files.
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=373764
http://slive.ytn.co.kr:1935/live/ylive_0624_1.sdp/playlist.m3u8?wowzasessionid=1093961187
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=382539
http://slive.ytn.co.kr:1935/live/ylive_0624_1.sdp/playlist.m3u8?wowzasessionid=1566364859
etc...
Although I can play the url http://slive.ytn.co.kr:1935/live/ylive_0624_1.sdp/playlist.m3u8?wowzasessionid=195968950 in safari in my iphone, I want to play this url in my own iphone app.
How can I play m3u8 file extension by myself?
EDIT - May be a duplicate of this SO question but if you want to persist the file, you'll need to go the hard way listed below.
Easy way = Embed UIWebView in your app and initialize it with the url of the .m3u8 file. This will open up quicktime which understands m3u8 and it will play it as it downloads.
Hard way = manually create the request/responses for each part of the m3u8 session and then download each .ts file in turn from the playlist file. As you get each "chunk" of the video, write it to a file or memory, then append the next "chunk" after it. I've done this for a h.264 encoded .m4v file served as a m3u8 and it worked (my code is too ugly to paste) but the pseudocode is:
Fetch the m3u8, saving any cookies sent and any headers that may be important*
Parse the .m3u8 (the first file, with the #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=373764) and pull our the urls.
Fetch the playlist from one of the URLs in the .m3u8 file (being sure to keep any headers/cookies in the request that may be necessary)
Parse the playlist file, saving as much metadata as you need from the top part of the file, construct an absolute URL for each .ts path, then stuff it into an array.
Iterate over the array (again, being mindful of cookies/headers) and fetch the content of each .ts URL into a file.
Play the downloaded file with whichever Media Framework you choose (search SO for how to do this)
If you just need to play the files, go the easy route. If you need to persist them, you need to do the m3u8 dance.
*HTTP Scoop is invaluable for seeing how the m3u8 "protocol" works and for making sure you're request/response headers are accurate - http://tuffcode.com/
*I used vanilla NSURLConnection synchronous calls as my code was just a proof of concept, other network frameworks like AFNetworking will make this a lot easier.

Record audio, add effects, then save result to a audio file

I am having trouble doing what the title said. My goal is to be able to add any desired effects to your recording, save the modified audio, then send that to a server.
I have searched the fourms and came across these threads:
viewtopic.php?f=7&t=13029&p=45362&hilit=saving#p45362
viewtopic.php?f=7&t=12660&p=44586&hilit=saving#p44586
viewtopic.php?f=7&t=13178&p=45746&hilit=saving#p45746
After reading those, I see it is possible to save the modified audio, but can it only be saved as a wav? Like I said after it is saved it will be sent to a server, so size is a big deal and wavs are relatively big compared to other formats. Ignoring that fact, I tried to implement FMOD_OUTPUTTYPE_WAVWRITER and I cannot get that to work; are there any good examples of using it? I looked though the examples in the library but I didn't see any..
But the basic structure of the app is to record, turn some switches off and on to see what filters you want, preview it, then press a button "Save" that will save it. What would this save function consist of?
Any help appreciated, thanks.
Using FMOD_OUTPUTTYPE_WAVWRITER is fairly straight forward, you set the type via System::setOutput, specify the output file via System::init extradriverdata. The extradriverdata should be an absolute path to a writable area of the device such as the documents directory. After you have finished playing, call System::release and the file will be complete.
The other option for recording wave data with effects is by creating a custom DSP and connecting it to the channel playing the recorded data. You will then get regular callbacks giving you float data that you must write out to disk yourself. You can find examples of DSPs and writing wav files in the dsp_custom and recordtodisk examples respectively.
Finally note that FMOD doesn't come with the facility to write compressed audio to disk, you will need another API to achieve this goal.
You can save as an AAC file via the ExtAudioFile API.