OpenNi: set Player node for OpenFileRecording - c++

I searched on web for this problem but I didn't find a solution.
I'm starting to use samples of OpenNI to develop my application. I have not much experience with C++: I am a beginner.
I'm using SimpleSkeleton sample of OpenNI 1.5.4 which returns head position. I need it but using an ONI file which I got recording using NiViewer, and not the stream data from kinect.
Searching on web I found:
xn::Context context;
xn::Player player;
nRetVal = context.Init();
nRetVal=context.OpenFileRecording("Myfile.oni",player);
if (nRetVal != XN_STATUS_OK)
{
printf("Can't open recording file: %s\n",xnGetStatusString(nRetVal));
return 1;
}
My code enter the if loop, print 'Can't open my file.oni ...' and doesn't continue running.
I think the problem is to set player object. How can I do? Or what have I to do?
Without the lines:
nRetVal=context.OpenFileRecording("Myfile.oni",player);
if (nRetVal != XN_STATUS_OK)
{
printf("Can't open recording file: %s\n",xnGetStatusString(nRetVal));
return 1;
}
it runs correctly but use data stream from kinect and not from file.

Even if it seems like it's not, this is a path issue.
I had a similar problem, you're either passing it to OpenNI in a way it does no like, or the path is not valid.
How are you retrieving the path? Trying using boost to get the current-directory and then appending the .oni file name to that string

Related

Allegro5 C++: Audio sample can't be loaded

I'm trying to insert a song that plays on a loop in my c++ Allegro 5 game. It keeps saying that it can't load the audio.
I have:
tried to use .wav and .ogg files, both did not work.
put the audio file in the correct directory.
created a function to detect the error.
initialized al_init_acodec_addon() and al_install_audio()
ALLEGRO_SAMPLE* song = al_load_sample("liar.ogg");
void game_begin()
{
if (!song)
{
printf( "Audio clip sample not loaded!\n" );
show_err_msg(-6);
}
//Loop the song until the display closes
al_play_sample(song, 1,0,1,ALLEGRO_PLAYMODE_LOOP, NULL);
Basically the console almost always prints out the error message no matter what I do.
Is this a known Allegro 5 problem? I still can't think of a way to fix this...
On a side note, I have tested loading & playing audio in another project file and it worked. Is my file cursed? :(
:)
Try to put it in THIS ORDER before loading samples:
if(!al_init())
return -1;
if(!al_install_audio())
return -2;
if!(!al_init_acodec_addon()) // after installing audio
return -3;
if(!al_reserve_samples(1))
return -4;
And what do you mean by correct directory?

Reading a saved EVTX file in the given path

I am currently working on a project where I need to read windows events .
I am using OpenEventLog() and ReadEventLog() from Win API. I can read the events from system using the typename of the event.
But I need to specify the file name or file path of the .evtx file that I have saved from the EventViewer.I tried the below code,
HANDLE logHandle = OpenEventLog(NULL, "C:\\Users\\MyAccount\\Documents\\myevents.evtx");
DWORD status = GetLastError();
if(logHandle == NULL){
cerr<<"NO HANDLE GENERATED!!!"<<endl;
}else if(status == ERROR_INVALID_HANDLE){
cerr<<"INVALID HANDLE!!!"<<endl;
}else if(status!=0){
cout<<"OPENEVENTLOG ERROR STATUS::>"<<status<<endl;
}
But it does not find the specified file and switches over to default Application Events. Can anyone please tell me what the problem could be? or if there is anything to be changed in the code?
PS: I even tried placing the file in project folder and specifying just the filename(myevents.evtx) , but still doesn't work.I also tried reading the evtx directly as shown in "Reading .evt/.evtx files directly" , but later I found this can't be done. Apparently there is no way to read them directly without win API or without writing a whole bunch of parser code.
Thanks in advance.
Well, it turns out OpenEventLog() is not meant for opening saved .evtx files.
I should've been using OpenBackupEventLog() for that.

C++ ofstream: Can't find output file

I have created the a default DirectX12 application (the spinning 3D cube) and within my void DX::DeviceResources::Present() I am trying to write the backbuffer to a file:
// Present the contents of the swap chain to the screen.
void DX::DeviceResources::Present()
{
// The first argument instructs DXGI to block until VSync, putting the application
// to sleep until the next VSync. This ensures we don't waste any cycles rendering
// frames that will never be displayed to the screen.
HRESULT hr = m_swapChain->Present(1, 0);
UINT backBufferIndex = m_swapChain->GetCurrentBackBufferIndex();
ComPtr<ID3D12Resource> spBackBuffer;
m_swapChain->GetBuffer(backBufferIndex, IID_PPV_ARGS(&spBackBuffer));
//before writing the buffer, I want to check that the file is being
//created
ofstream myfile;
myfile.open("WHEREISTHEFILE.txt");
myfile << "Writing this to a file.\n";
myfile.close();
// If the device was removed either by a disconnection or a driver upgrade, we
// must recreate all device resources.
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
m_deviceRemoved = true;
}
else
{
DX::ThrowIfFailed(hr);
MoveToNextFrame();
}
}
The problem occurs here:
ofstream myfile;
myfile.open("WHEREISTHEFILE.txt");
myfile << "Writing this to a file.\n";
myfile.close();
I just want to write a file first (as illustrated how here), before trying to write the contents of the back buffer. Now, for some reason, I cannot find the output file... I have searched everywhere, all directories in my project and even in the Microsoft DirectX SDK folder.
There are no exceptions thrown and I can step through each line while debugging without error.
Where could it be?
It should be in the directory of your project. If you are using Visual Studio, you can right-click your solution and click Open folder in File explorer.
Image: Open folder in File explorer
(I embedded it like this because I need 10 reputation to post an image directly)
Also with your code now, there is no way to determine whether your program is actually able to open the output file or not. I suggest you use something like this:
std::ofstream outputFile("./myOutput.txt");
if (outputFile.fail())
{
std::cout << "Failed to open outputfile.\n";
}
outputFile << "I like trains.";
outputFile.close();
The first line is an initialisation that does the same as .open(). Also mind the "./" in front of the path, this should not be mandatory but it can't hurt to do this (this means your current directory).
The important part about this piece of code is the .fail() check, if your program failed to open the outputfile, you will ofcourse not be able to find it anywhere. Hope this helped!
Where could it be?
Usually the file location is relative to your current working directory, i.e. WHEREISTHEFILE.txt should be located in whatever directory you were in when you started the program.
You can determine that directory inside your program via GetCurrentDirectory(), and change it to something else via SetCurrentDirectory().
But you did not check if the .open() was successful, so the writing could have failed altogether, for example due to insufficient permissions...?!

How to extract audio form video using ffmpeg in C++?

I'm developing a C++ app that uses FFmpeg to play audio/video. Now I want to enhance the application to allow the users to extract audio from video. How can FFmpeg can be used for this? I searched a lot about this but I was not able to find a tutorial regarding it.
You need to
Open the input context [ avformat_open_input ]
Get the stream information [ avformat_find_stream_info ]
Get the audio stream:
if (inputFormatContext->streams[index]->codec->codec_type ==
AVMEDIA_TYPE_AUDIO) {
inputAudioStream = inputFormatContext->streams[index];
}
Read each packet.
AVPacket packet;
int ret = av_read_frame(inputFormatContext, &packet);
if (ret == 0) {
if (packet.stream_index == inputAudioStream->index) {
// packet.data will have encoded audio data.
}
}
This seems like a simple scripting task... why do you want to use the heavy artillery (C/C++) to swat a fly?
I use Applescript to build/run an ffmpeg command line via a Bash shell. The only reason I involve Applescript is so I can invoke it as a droplet (ie drag-and-drop the file(s) onto the app and have it run without interaction.)
I get that you're probably on Windows, meaning no Applescript and no Bash. But surely something lighter than C can build/run an ffmpeg command line. It's really as simple as:
ffmpeg -i infile.mp4 -b 160k outfile.mp3

How to use ffmpeg faststart flag programmatically?

I try to convert videos for playback on Android using H264, AAC codecs and mp4 container. Video plays normaly with non-system players. But system player shows error "Can't play this video".
I found out that the problem is in moov atom, which is writed in the end of the file.
When I use "-movflags +faststart" ffmeg flag to convert video, it plays normal, but when I try to do that programmatically, it gives no result. I use following code:
av_dict_set( &dict, "movflags", "faststart", 0 );
ret = avformat_write_header( ofmt_ctx, &dict );
This code works fine:
av_dict_set( &dict, "movflags", "faststart", 0 );
ret = avformat_write_header( ofmt_ctx, &dict );
But problem is not solved. I still can't play converted videos on Android devices.
I assume that this answer is very late, but still, for anyone who might still be facing the same issue: this might be caused by the AV_CODEC_FLAG_GLOBAL_HEADER not being set in the audio/video AVCodecContext. A lot of guides show that it needs to be set in the AVFormatContext, but it needs to be set in the AVCodecContext before opening it using avcodec_open2.
if (format_context->oformat->flags & AVFMT_GLOBALHEADER) {
video_codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
avcodec_open2(video_codec_context, video_codec, nullptr);
Maybe the video is not compatible with your android phone? Try to convert with h264 baseline profile.
TL;DR
Set url field of AVFormatContext before avformat_write_header.
Why
I hit same issue today, and I found there is a log when calling av_write_trailer:
Unable to re-open output file for the second pass (faststart)
In the movenc.c implementation, we can see it needs s->url to re-open the file:
avio_flush(s->pb);
ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
"the second pass (faststart)\n", s->url);
goto end;
}