vendredi 4 octobre 2013

Screen capture with ffmpeg.

ffmpeg is the perfect tool to transcode video, but you may don’t know that it can also be use to capture your PC’s screen and as I didn’t found a clear page explaining how to do that, I will try to do my own (and hope it will help someone ….)

Performing a screen capture is an usual task to report bug, recording a presentation you make (adding your voice and your webcam recoding over-the-top of your slide), etc…

There is several tools you can found under the web (GOOGLE IT), But you have to setup a new application, you don’t even control the Audio/Video filter used to capture and encode the video. If you want to keep control, you would like my command line based solution.

Note that the solution I describe here is for Windows, but it could also work under Linux  with some adaptation, look at –x11grab)

First, check if you have Audio & Video Capture filter:

ffmpeg -list_devices true -f dshow -i dummy
it should return something like:


dshow @ 00000000002fb2e0] DirectShow video devices

dshow @ 00000000002fb2e0]  "…."

dshow @ 00000000002fb2e0] DirectShow audio devices

dshow @ 00000000002fb2e0]  "…."


If you don’t find a filter name between the quotes, you have to setup filters and /or enable the audio output recoding capabilities.


  • Setup Video Capture filter for x86 and x64 (it depend of your ffmpeg version).

I recommend the Unreal Screen Capture DirectShow source filter , download the version you need and perform the installation.



  • Setup the Audio Capture. That part depends of your device, but for example on my PC, I have a “Realtek High Definition Audio” Device. I clicked on the speakers icon in the system bar and select “recording device”, I had to enable the “stereoMix” device and boost its capture level.

EnableAudioOutRecording


After check again if ffmpeg detect your device/filter, it should be something like:



dshow @ 00000000002fb2e0] DirectShow video devices

dshow @ 00000000002fb2e0]  "UScreenCapture"

dshow @ 00000000002fb2e0] DirectShow audio devices

dshow @ 00000000002fb2e0]  "Stereo Mix (Realtek High Defini"


Run your 1st capture



ffmpeg -f dshow -i video="UScreenCapture":audio=Stereo Mix (Realtek High Defini" cap.mp4


Just hit [q] to stop the recoding and play cap.mp4 (ffplay cap.mp4).


By default, it capture the whole screen, and the whole means ALL your screen i.e. for my dual-screen system I recorded a 3840x1200 video.


Select your ROI(Region Of Interest)


We will use the -vf crop=width:height:xtopleft:ytopleft syntax of ffmpeg to select the part of the big picture we really want to record.


For the example, we will capture the output of a video player, but how to get the windows or video area coordinates ? In fact it’s really simple, I use the small application called “Point Position”.


 


PointPosition


Using that tool you can get the top-left and bottom-right coordinate of any window you want to capture, and by the way compute the width and height of the area!


Now capture:



fmpeg -f dshow -r 14.985 -i video="UScreenCapture":audio="Stereo Mix (Realtek High Defini" -vf crop=1278:541:98:198,scale=480:270 -c:v libx264 -profile:v baseline -level:v 3.0 -b:v 350k -r 14.985 -pix_fmt yuv420p cap.mp4


here I added several option to set a capture frame-rate, rescale the cropped area and encode the video using explicit parameters (encoder, bit-rate, etc….)


Conclusion:


No need of additional tool to perform a task that our video’s Swiss knife can do !

vendredi 27 septembre 2013

Windows PATH Environment Variable too long!

 

Yesterday, I unzipped several useful command line tools each in their respective folder and tried to add all those path in my PATH to easily access all tools from any command prompt, BUT ….

When I tried to copy/paste all the new path through the Environment Variables Editor, you can open from :

“Control Panel\System and Security\System”, click on “Advanced system settings”, select “Advanced” Tab and now click on the “Environment Variables” button…..

Smile  a shortcut will be welcome !

The Editor here has a 2048 characters limit. And I already have a too long path !!!!

An easy workaround from here was to use the “User” PATH as I’m the only user of my workstation it was fine.

But If you really need to update the PATH for all users you can use the registry editor (regedit.exe):

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path

The Editor (rigth click on the key and select “Modiffy”) will allow you to use more characters.

But if one day your change are finally truncate, It could mean you hit the maximum of 32767 characters (CONSIDERING ALL YOUR VARIABLES ….)

mardi 17 septembre 2013

Coding Style: Detect tabulation and use a given number of space instead.

 

If you need to respect a Coding Style, and that your coding style require tab to be replaced by a given number of space (2 in my case), you may have to check before each commit that the files you have in your working copy doesn’t contain any tab.

To realize that preliminary step, you can use grep.

Run: grep -n -P "\t" *.h && grep -n -P "\t" *.cpp

It will get you the file name and the line number where grep found tabulation.

Now if we want to automatically apply the Coding Styles rules and replace tabs by 2 spaces we can also use a command line.

find ./ -type f -name "*.h" -exec sed -i 's/\t/  /g' {} \;

and

find ./ -type f -name "*.cpp" -exec sed -i 's/\t/  /g' {} \;

The number of space between \t/ and /g has to be the number of space for tab !

Note that grep, find and sed are Linux command, but Windows developer can also use those command if they setup Cygwin.

lundi 16 septembre 2013

C++: Find max top 5 number from 3 array.


Yesterday, I read that blog post where C# developer demonstrate how powerful is LINQ to solve a simple problem.
We have 3 array of Integer  and we want to find the 5 maximum number from those 3 Array.  With LINQ, 7 cascaded operation are enough to do that in 3 line of code.
And I’m wondering how many line I would use in C++ to do the same !
Here is my 1st Draft made in 5min. I use only 5 line of code.
//Headers we need
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>

using namespace std;

int Array1 [] = { 9, 65, 87, 89, 888 };
int Array2 [] = { 1, 13, 33, 49, 921 };
int Array3 [] = { 22, 44, 66, 88, 110 };

vector<int> A1(begin(Array1), end(Array1)); 
A1.insert(end(A1), begin(Array2), end(Array2)); 
A1.insert(end(A1), begin(Array3), end(Array3));
sort(begin(A1), end(A1));
vector<int> max(end(A1)-5, end(A1));

//to output the result
copy(begin(max), end(max), ostream_iterator<int>(cout, " "));




But I would see on Stack Overflow if someone has a better solution.

[UPDATE] : you can found interesting to read answer to my StackOverFlow question.
 C++ and C++11 solution are proposed, taking into account the complexity introduce by the sorting. 

jeudi 12 septembre 2013

Let your hand on the keyboard.

 

I don’t know all the “magic” keyboard shortcut but I always try to learn new shortcut, just because typing and switching between keyboard and mouse is just losing time.

Today I was try to get a shortcut for word/outlook word spell suggestion and find that it’s easy. If the spell checker is enable and that something you just typed appears with the red-underline (saying something is wrong), get back on that word and use MAJ+F10 to open the suggestion list.

Now I can correct a lot of typo mistake on-the-fly without living my keyboard !

C++/Boost Finding files in a folder.

 

Interaction with the file system are not so easy to implement using C++, and that’s where Boost can help you. Boost contain a lot of useful libraries, and FileSystem is one I used the the most.

To build a simple example, let say that we would go through all files in a given folder and remove them with a specific extension '.bak.

First include boost FileSystem header file and I would recommend to use a namespace alias to reduce the length of your code line (typing boost::filesystem:: blahblah every time is too long !)

#include "boost/filesystem.hpp"
namespace fs = boost::filesystem;



Now we have to define the folder path and directory_iterator

fs::path outputFolder(".");
for(fs::directory_iterator it(outputFolder); it != fs::directory_iterator() ; ++it)
{
....
}



Here we iterate over files in the current directory of the program. But using a specific path string you could reach all accessible folder.


Now in the loop, using the valid directory_iterator it, you can do a lot of different things. Below I will test if extension is .bak and if true remove that file.

if(fs::extension(it.path().filename()) == ".bak") 
{
fs::remove(file);
}



Now you can still rely to system command and that you don’t have to del with different FileSystem, under windows just use the system function (<stdio.h>) like : system(‘del *.bak”);


It mainly depend of your project, because adding and using Boost for using only one  of those functionality may be a bad idea.

jeudi 5 septembre 2013

Terminal 2–Don’t assign CTRL+C for Copy

 

Terminal 2 is a powerful tools under windows to run cmd.exe, Cygwin bash and other command prompt. Users can customized their hot-key (hit CTRL+S to open the Settings dialog box). But if you assign the CTRL+C keyboard shortcut for the common “Copy to clipboard” action, you may have trouble in killing programs you run.

Prefer the “copy on select” behavior and re-assign the copy action to another shortcut (i.e. SHIFT+CTRL+C).

After that change, you run program and stop them with CTRL+C as in the classic cmd.exe (windows prompt)