MoSync - Edit video - c++

After making a small video recorder application and being able to play that video again. I would like to make the possibility to pick X seconds from the video and put that into a new .MP4 file (or overwrite the old one, that would be even better).
I am using the MoSync C++ Native UI and VideoViewer. I know I can get the position and that part is all fine, and according to the MoSync documentation.
char buf[BUFFER_SIZE];
maWidgetGetProperty(videoViewHandle,
MAW_VIDEO_VIEW_CURRENT_POSITION,
buf,
BUFFER_SIZE);
int seconds = 5;
//So here I need to make a new file ranging from buf to buf + seconds
However, I have absolutely no clue as to where to look for this. Should I use mp4 header files and create my own mp4 (how is this even done? and is this cross-compatible?).
Will appreciate any advice/help you can offer!

Related

mp3 to sample array NAudio

How can I use NAudio library to get sample float array from mp3 file?
Here is my code:
float[] buffer = new float[2000];
AudioFileReader reader = new AudioFileReader(filePath);
reader.Read(buffer, 0, 2000);
After that buffer is always empty (only zeros inside).
You could also provide me another useful library in C# to realize this.
You're reading the first 2000 samples which is only going to be around 20ms of audio, so it's quite possible that your MP3 starts with a bit of silence. Have you tried reading further into the file?

C++ - CGI - Audio not working properly

I have a website with an HTML5 audio element whose audio data shall be served via a cgi script.
The markup is rather simple:
<audio controls>
<source type="audio/mpeg" src="audio.cgi?test.mp3">
<em>Me, your browser does not support HTML5 audio</em>
</audio>
The cgi is written in C++ and is pretty simple too, I know there is need of optimizing, e.g. reading the whole file in a buffer is really bad, but that's not the point.
This basic version kinda works, meaning the audio is played, but the player does not display the full length and one can only seek through the track in parts that have already been played.
If the audio file is placed in a location accessible via the web-server everything works fine.
The difference between these two methods seems to be, that the client issues a partial-content request if the latter method is chosen and an ordinary 200 if I try to serve the audio data via the cgi at once.
I wanted to implement partial-content serving into the cgi but I failed to read out the environment variable Request-Range, which is needed to serve the requested part of data.
This leads me to my questions:
Why does the HTML5 player not display the full length of the track if I'm serving the audio data via the cgi script?
Would implementing a partial-content handling solve this issue?
If the partial-content handling is the right approach, how would I access the required environment variables in apache, since I have not found anything about them? Do I need to send a complete HTTP header indicating partial-content is coming, so the client knows he needs to send the required fields?
This is the source of the .cgi:
void serveAudio()
{
//tried these, were not the right ones
//getenv("HTTP_RANGE");
//getenv("HTTP_CONTENT_RANGE");
ifstream in(audioFile, ios::binary | ios::ate);
size_t size = in.tellg();
char *buffer = new char[size];
in.seekg(0, ios::beg);
in.read(buffer, size);
cout<<"Content-Type: audio/mpeg\n\n";
cout.write(buffer, size);
}
Any suggestions and helpful comments are appreciated!
Thanks in advance!
P.S.:
Forgot to mention that this behaviour applies to FF 31 and IE 11.

Reading midi-files

I'm trying to help out a friend creating a program. And we need to read some midi-file data. I've searched for a good 2 hours now and I can't really seem to find any straight forward ways of doing it.
I've downloaded and hopefully installed SDL_mixer correctly. And managed to play a song with this:
//Initialize sound
SDL_Init(SDL_INIT_AUDIO);
Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024);
Mix_VolumeMusic(100);
//Load song
string midiFile = LIB_AUDIO + "redlottery.mid";
Mix_Music *song = Mix_LoadMUS(midiFile.c_str());
//Play song
Mix_PlayMusic(song, 1);
So, what I'm wondering is... Is it possible to extract data using this?
I need things like, note timings. I don't really know how they are structured, but I want to access data. How do you suggest I try doing that?
Thanks!
There are open-source libraries for reading MIDI files. Here are a few:
midifile.sapp.org
naudio.codeplex.com
www.juce.com

Copy QuickTime audio to another QuickTime movie

I'm trying to copy a section of audio from one QuickTime movie to another one but without success; the audio doesn't seem to be copied.
C++ basic code:
// Copy from another QT movie, *src, to this one
soundTrack = NewMovieTrack(myMovie, 0, 0, kFullVolume);
soundMedia = NewTrackMedia(soundTrack, SoundMediaType,
GetMediaTimeScale(src->soundMedia), NULL, 0);
BeginMediaEdits(soundMedia);
InsertTrackSegment(src->soundTrack, soundTrack, 0,
GetMediaDuration(src->soundMedia), 0);
EndMediaEdits(soundMedia);
I don't want to transcode the sound, just copy the encoded sound frames across. I realise this basic code will copy all of the sound frames in the movie.
I am doing some other editing with the video file so I don't want to go through QTKit if I can possibly help it.
The code is good, I can get sound using it. I made some mistake in another part and ended up selecting the wrong source sequence for the sound. Sorry about that.

C++ : What's the easiest library to open video file

I would like to open a small video file and map every frames in memory (to apply some custom filter). I don't want to handle the video codec, I would rather let the library handle that for me.
I've tried to use Direct Show with the SampleGrabber filter (using this sample http://msdn.microsoft.com/en-us/library/ms787867(VS.85).aspx), but I only managed to grab some frames (not every frames!). I'm quite new in video software programming, maybe I'm not using the best library, or I'm doing it wrong.
I've pasted a part of my code (mainly a modified copy/paste from the msdn example), unfortunately it doesn't grabb the 25 first frames as expected...
[...]
hr = pGrabber->SetOneShot(TRUE);
hr = pGrabber->SetBufferSamples(TRUE);
pControl->Run(); // Run the graph.
pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it's done.
// Find the required buffer size.
long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
for( int i = 0 ; i < 25 ; ++i )
{
pControl->Run(); // Run the graph.
pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it's done.
char *pBuffer = new char[cbBuffer];
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);
AM_MEDIA_TYPE mt;
hr = pGrabber->GetConnectedMediaType(&mt);
VIDEOINFOHEADER *pVih;
pVih = (VIDEOINFOHEADER*)mt.pbFormat;
[...]
}
[...]
Is there somebody, with video software experience, who can advise me about code or other simpler library?
Thanks
Edit:
Msdn links seems not to work (see the bug)
Currently these are the most popular video frameworks available on Win32 platforms:
Video for Windows: old windows framework coming from the age of Win95 but still widely used because it is very simple to use. Unfortunately it supports only AVI files for which the proper VFW codec has been installed.
DirectShow: standard WinXP framework, it can basically load all formats you can play with Windows Media Player. Rather difficult to use.
Ffmpeg: more precisely libavcodec and libavformat that comes with Ffmpeg open- source multimedia utility. It is extremely powerful and can read a lot of formats (almost everything you can play with VLC) even if you don't have the codec installed on the system. It's quite complicated to use but you can always get inspired by the code of ffplay that comes shipped with it or by other implementations in open-source software. Anyway I think it's still much easier to use than DS (and much faster). It needs to be comipled by MinGW on Windows, but all the steps are explained very well here (in this moment the link is down, hope not dead).
QuickTime: the Apple framework is not the best solution for Windows platform, since it needs QuickTime app to be installed and also the proper QuickTime codec for every format; it does not support many formats, but its quite common in professional field (so some codec are actually only for QuickTime). Shouldn't be too difficult to implement.
Gstreamer: latest open source framework. I don't know much about it, I guess it wraps over some of the other systems (but I'm not sure).
All of this frameworks have been implemented as backend in OpenCv Highgui, except for DirectShow. The default framework for Win32 OpenCV is using VFW (and thus able only to open some AVI files), if you want to use the others you must download the CVS instead of the official release and still do some hacking on the code and it's anyway not too complete, for example FFMPEG backend doesn't allow to seek in the stream.
If you want to use QuickTime with OpenCV this can help you.
I have used OpenCV to load video files and process them. It's also handy for many types of video processing including those useful for computer vision.
Using the "Callback" model of SampleGrabber may give you better results. See the example in Samples\C++\DirectShow\Editing\GrabBitmaps.
There's also a lot of info in Samples\C++\DirectShow\Filters\Grabber2\grabber_text.txt and readme.txt.
I know it is very tempting in C++ to get a proper breakdown of the video files and just do it yourself. But although the information is out there, it is such a long winded process building classes to hand each file format, and make it easily alterable to take future structure changes into account, that frankly it just is not worth the effort.
Instead I recommend ffmpeg. It got a mention above, but says it is difficult, it isn't difficult. There are a lot more options than most people would need which makes it look more difficult than it is. For the majority of operations you can just let ffmpeg work it out for itself.
For example a file conversion
ffmpeg -i inputFile.mp4 outputFile.avi
Decide right from the start that you will have ffmpeg operations run in a thread, or more precisely a thread library. But have your own thread class wrap it so that you can have your own EventAgs and methods of checking the thread is finished. Something like :-
ThreadLibManager()
{
List<MyThreads> listOfActiveThreads;
public AddThread(MyThreads);
}
Your thread class is something like:-
class MyThread
{
public Thread threadForThisInstance { get; set; }
public MyFFMpegTools mpegTools { get; set; }
}
MyFFMpegTools performs many different video operations, so you want your own event
args to tell your parent code precisely what type of operation has just raised and
event.
enum MyFmpegArgs
{
public int thisThreadID { get; set; } //Set as a new MyThread is added to the List<>
public MyFfmpegType operationType {get; set;}
//output paths etc that the parent handler will need to find output files
}
enum MyFfmpegType
{
FF_CONVERTFILE = 0, FF_CREATETHUMBNAIL, FF_EXTRACTFRAMES ...
}
Here is a small snippet of my ffmpeg tool class, this part collecting information about a video.
I put FFmpeg in a particular location, and at the start of the software running it makes sure that it is there. For this version I have moved it to the Desktop, I am fairly sure I have written the path correctly for you (I really hate MS's special folders system, so I ignore it as much as I can).
Anyway, it is an example of using windowless ffmpeg.
public string GetVideoInfo(FileInfo fi)
{
outputBuilder.Clear();
string strCommand = string.Concat(" -i \"", fi.FullName, "\"");
string ffPath =
System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\ffmpeg.exe";
string oStr = "";
try
{
Process build = new Process();
//build.StartInfo.WorkingDirectory = #"dir";
build.StartInfo.Arguments = strCommand;
build.StartInfo.FileName = ffPath;
build.StartInfo.UseShellExecute = false;
build.StartInfo.RedirectStandardOutput = true;
build.StartInfo.RedirectStandardError = true;
build.StartInfo.CreateNoWindow = true;
build.ErrorDataReceived += build_ErrorDataReceived;
build.OutputDataReceived += build_ErrorDataReceived;
build.EnableRaisingEvents = true;
build.Start();
build.BeginOutputReadLine();
build.BeginErrorReadLine();
build.WaitForExit();
string findThis = "start";
int offset = 0;
foreach (string str in outputBuilder)
{
if (str.Contains("Duration"))
{
offset = str.IndexOf(findThis);
oStr = str.Substring(0, offset);
}
}
}
catch
{
oStr = "Error collecting file information";
}
return oStr;
}
private void build_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
string strMessage = e.Data;
if (outputBuilder != null && strMessage != null)
{
outputBuilder.Add(string.Concat(strMessage, "\n"));
}
}
Try using the OpenCV library. It definitely has the capabilities you require.
This guide has a section about accessing frames from a video file.
If it's for AVI files I'd read the data from the AVI file myself and extract the frames. Now use the video compression manager to decompress it.
The AVI file format is very simple, see: http://msdn.microsoft.com/en-us/library/dd318187(VS.85).aspx (and use google).
Once you have the file open you just extract each frame and pass it to ICDecompress() to decompress it.
It seems like a lot of work but it's the most reliable way.
If that's too much work, or if you want more than AVI files then use ffmpeg.
OpenCV is the best solution if video in your case only needs to lead to a sequence of pictures. If you're willing to do real video processing, so ViDeo equals "Visual Audio", you need to keep up track with the ones offered by "martjno". New windows solutions also for Win7 include 3 new possibilities additionally:
Windows Media Foundation: Successor of DirectShow; cleaned-up interface
Windows Media Encoder 9: It does not only include the programm, it also ships libraries for coding
Windows Expression 4: Successor of 2.
Last 2 are commercial-only solutions, but the first one is free. To code WMF, you need to install the Windows SDK.
I would recommend FFMPEG or GStreamer. Try and stay away from openCV unless you plan to utilize some other functionality than just streaming video. The library is a beefy build and a pain to install from source to configure FFMPEG/+GStreamer options.