How to add metadata to WAV file? - metadata

I'm looking for some sample code to show me how to add metadata to the wav files we create.
Anyone?

One option is to add your own chunk with a unique id. Most WAV players will ignore it.
Another idea would to be use a labl chunk, associated with a que set at the beginning or end of the file. You'd also need a que chunk. See here for a reference
How to write the data is simple
Write "RIFF".
save the file position.
Write 4 bytes of 0's
Write all the existing chunks. Keep count of bytes written.
Add your chunk. Be sure to get the chunksize right. Keep
count of bytes written.
rewind to the saved position. Write the new size (as a 32-bit
number).
Close the file.
It's slightly more complicated if you are adding things to an existing list chunk, but the same principle applies.

Maybe the nist file format will give you what you want:
NIST
Here is a lib that could help, but im afraid it looks old. NIST Lib
Cant find more useful information right now how exactly to use it, and im afraid the information papers from my company must stay there. :L/

Try code below
private void WaveTag()
{
string fileName = "in.wav";
WaveReadWriter wrw = new WaveReadWriter(File.Open(fileName, FileMode.Open, FileAccess.ReadWrite));
//removes INFO tags from audio stream
wrw.WriteInfoTag(null);
//writes INFO tags into audio stream
Dictionary<WaveInfo, string> tag = new Dictionary<WaveInfo, string>();
tag[WaveInfo.Comments] = "Comments...";
wrw.WriteInfoTag(tag);
wrw.Close();
//reads INFO tags from audio stream
WaveReader wr = new WaveReader(File.OpenRead(fileName));
Dictionary<WaveInfo, string> dir = wr.ReadInfoTag();
wr.Close();
if (dir.Count > 0)
{
foreach (string val in dir.Values)
{
Console.WriteLine(val);
}
}
}
from http://alvas.net/alvas.audio,articles.aspx#id3-tags-for-wave-files

If you examine the wave file spec you'll see that there does not seem to be room for annotations of any kind. An option would be to wrap the wave file with your own format that includes custom information but you would in effect be creating a whole new format that would not be readable by users who do not have your app. But you might be ok with that.

Related

Is it possible to reorder and recombine fragments in fmp4?

I have fragmented mp4 which I want to send users through HLS. It's ok if I just send it as is. But I need opportunity to reorder fragments in this video.
For example initial video, which looks like this:
original video format
I want reorganize fragments and get this:
expected video format
I try make it locally, and it's work in VLS player (HLS). For this I modified sequence number for fragments in moof (mfhd). But when I try play it remotely (HLS) it does not work. I think, that some players (js) expect some additional information from each fragment, probably for example time offset. But I can not find which atom (box) contain this information. I spent a lot of time searching and I'm still at the very beginning of the problem.
I tried to modify the fragment sequence number, but it doesn't work.
The "Track Fragment Media Decode Time Box" (tfdt) stores the baseMediaDecodeTime which is the accumulative decode time.
Consider the following...
baseMediaDecodeTime must increase monotonically for each chunk.
This means you must update (replace) the tfdt entry of chunk with expected next tftd entry.
When you naively reorder the chunks, the baseMediaDecodeTime will be invalid.
The "Track Fragment Media Decode Time Box" (tfdt) is located inside each moof header at:
moof --> traf --> tfdt

How load/save a number with saved games for Play Games Services in Unity games?

I need to load/save the number of coins a user has earned in my Unity game with saved games for Play Games Services.
There is an example on how to save an image on this page: https://developer.android.com/games/pgs/unity/saved-games#write_a_saved_game
Can someone tell me how I can load/save a number instead of an image?
To be precise, I wouldn't say you are exactly saving an image. I mean, you do save it, but only as a cover for your game save file and I don't know if you can retrieve it (maybe you can, I haven't checked that really).
Probably the most important part of using google play save system is byte[] savedData argument. It's just a byte array, and it's up to you what are you going to pass there and how are you going to interpret that data on game load.
There are a lot of ways you could approach it. I personally create a custom GameSave object with all my data that I want to save, then I serialize it using JsonUtility.
string json = JsonUtility.ToJson(gameSave);
After that, I use MemoryStream and BinaryFormatter to convert the data in my json to byte array:
MemoryStream memoryStream = new MemoryStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, json);
byte[] data = memoryStream.GetBuffer();
Then you would have to pass that data to savedGameClient.CommitUpdate method as an argument.
Of course, that's just one of the ways of doing that, you can send something else than json from serialized class object.
Other stuff is pretty well documented, so once you handle that, you should manage to do the rest.

Saving to .mp4 file in MATLAB

I'm editing all frames of an existing mp4 video in MATLAB (doing it in a for loop).
After I'm done editing, I want to save the new set of frames to a new output video file, but in mp4 rather than .avi (that seems to be the default).
I thought changing the filename extension is sufficient, but apparently it's not.
Any ideas?
newVid = VideoWriter(outputfilename);
newVid.FrameRate = fps;
newVid.Quality = 100;
open(newVid)
for...
writeVideo(newVid,imgs{i})%within the for loop saving one frame at a time
end
close(newVid)
Renaming the file is not sufficient. You also need to specify the codec you want. In your case, you need to include an additional parameter into the VideoWriter constructor that consists of the codec you want to use as a MATLAB
string. In your case, specify 'MPEG-4':
newVid = VideoWriter(outputfilename, 'MPEG-4'); % New
newVid.FrameRate = fps;
newVid.Quality = 100;
open(newVid);
for ...
% Rest of your code here
BTW, have a look at the documentation in the future. It clearly shows you what to do if you want to save to a new format, and not AVI: https://www.mathworks.com/help/matlab/ref/videowriter.html#input_argument_d0e1094625
You need to pass a profile argument to matlab's videowriter.
From Matlab Help, VideoWriter(filename,profile) creates a VideoWriter object and applies a set of properties tailored to a specific file format (such as 'MPEG-4' or 'Uncompressed AVI').
In your case, you need to pass the string MPEG-4 to the profile argument.

How do I use TagLib-Sharp to write custom (PRIV) ID3 frames?

Specifically, I'd like to write the Windows Media Player frames, such as theWM/MediaClassPrimaryID, WM/MediaClassSecondaryID and WM/WMCollectionGroupID frames.
I'm using PowerShell, but C# would be good too.
I'm a bit rusty, but the following should be mostly correct. I remember these tags being UTF-16 but you'll probably want to get an existing tag and try decoding its value with the Unicode encoder to be sure.
// Get or create the ID3v2 tag.
TagLib.Id3v2.Tag id3v2_tag = file.GetTag(TagLib.TagTypes.Id3v2, true);
if(id3v2_tag != null) {
// Get the private frame, create if necessary.
PrivateFrame frame = PrivateFrame.Get(id3v2_tag, "WM/MediaClassPrimaryID", true);
// Set the frame data to your value. I am 90% sure that these are encoded with UTF-16.
frame.PrivateData = System.Text.Encoding.Unicode.GetBytes(value);
}

Create a certain size file and filled with no data on iOS

I'm developing an iphone app, I need to create a certain size file on filesystem and filled with NO data first, then seek to a offset and write data when get data from somewhere else
How can I do it?
The lseek BSD function is explicitly capable of that.
man lseek:
The lseek() function allows the file offset to be set beyond the end of the
existing end-of-file of the file. If data is later written at this point,
subsequent reads of the data in the gap return bytes of zeros (until data is
actually written into the gap).
NSMutableData or fseek is probably what you want