Tuesday, May 12, 2009

Extract audio tracks from video

To extract audio tracks from videos:
ffmpeg -i video.aviInput #0, avi, from 'video.avi':
Duration: 00:55:21.8, start: 0.000000, bitrate: 1380 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 704x384, 25.00 fps(r)
Stream #0.1: Audio: mp3, 48000 Hz, stereo, 160 kb/s
Stream #0.2: Audio: mp3, 48000 Hz, stereo, 160 kb/s
Must supply at least one output file


With that command, we don't extract anything, but we can see the audio track amount.
We see, that the video has 2 audio tracks. To extract one:

ffmpeg -i video.avi -map 0.2 audio.mp3Input #0, avi, from 'video.avi':
Duration: 00:55:21.8, start: 0.000000, bitrate: 1380 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 704x384, 25.00 fps(r)
Stream #0.1: Audio: mp3, 48000 Hz, stereo, 160 kb/s
Stream #0.2: Audio: mp3, 48000 Hz, stereo, 160 kb/s
Must supply at least one output file


We'll get the second audio track into audio.mp3 file.

In the case that we want to extract all audio's from all video's:
j=1;for i in *.avi;
do ffmpeg -i "$i" -map 0.2 /home/pron/SubWorkspace/Audio$j.mp3;
((j++));done;


For each avi file, we'll get an Audio?.mp3 file.

Sunday, May 10, 2009

OpenOffice Tips

Starting Page Numbering on Page 2, and Other Ways to Mix Page Styles in a Document

This is very useful tip, due to you learn creating page styles for the index's pages and for the body. This way you separate different sections of your document.

http://openoffice.blogs.com/openoffice/2005/12/different_page_.html

Page numbering
Another useful tip. I got resolve a problem with the index table. Never use the Offset feature you can see in the page number field dialog! The ToC (Table of Contents) is based on the real page numbering, it doesn't take into account the offset feature. Moreover, your last page won't have any numbering if the correction is positive.

* Go to the first paragraph of the page to be renumbered, right click and select Paragraph.
* Go to the Text Flow tab, in the Breaks section, adjust the page number.

http://user.services.openoffice.org/en/forum/viewtopic.php?f=71&t=1221

Adding Captions
You can add captions (names) to images, tables and other objects in a document. The, you can create a index of table using this captions. For that, in the type combo box select Index of Tables, and in Categories select Captions.

http://wiki.services.openoffice.org/wiki/Documentation/OOo3_User_Guides/Writer_Guide/Adding_captions

Subtitle synchronizer

I have written a program to synchronize subtitle's file (srt format). But what i mean when i say synchronize? The reality is that the videos are recorded with differents fps (Frames per second). So if our film has been recorded in 24 fps, but the subtitle is created with a film with 25 fps, our subtitle we'll desynchronize each second. This happen because the film with 24 fps is reproducing faster (less frames in the same time). So to realize that our subtitles are desynchronized with the film, we'll see that the film is more desynchronized as long as time is passing.

The program needs to know when stars and ends the conversation in the video. So you have to look for in the video when is the first and last conversation. It would be more precise to see which are the first and last conversations in the subtitle file, and then you we'll find easier the star/end times in the video.

The way to use the program is the next:

./subsincro desynchronized_file.srt new_start_time new_end_time > synchronized_file.srt

For example:

Suppose that in my_serie.3x05.srt we have this:

1
00:00:18,268 --> 00:00:20,498
Let's keep those hammers working!

(...)

422
01:28:22,428 --> 01:28:26,057
How will you live, John?
- Day by day.

Then, we search this conversations in the video, and make a note of the real times in the video. Finally we execute the program with the new start/end time:

./subsincro my_serie.3x05.srt 00:00:05,520 01:24:31,120 > my_serie.3x05.syn.srt

Program code:
 /*
Copyright 2010 djtalo85@gmail.com
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/


/*****************************
SUBTITLES SYNCHRONIZER

usage: ./subsincro sub_file.str new_start_time new_end_time
example: ./subsincro Pron.3x01.srt 00:00:01,000 00:54:31,000

To create a new subtitle file, redirect the output.
example: ./subsincro Pron.3x01.srt 00:00:01,000 00:54:31,000 > Pron.3x01.new.srt

*****************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int new_start_time,new_end_time,old_start_time,old_end_time;
int aux_start_time,aux_end_time;
int gap=0, subIndex=1;
float time_desync;


char *timeToString(int time) {
char *outTime;
int hour,min,sec,ms;
div_t d;

outTime = (char *) malloc (13*sizeof(char));

d=div(time,1000*60*60);
hour = d.quot;
time= d.rem;

d=div(time,1000*60);
min= d.quot;
time = d.rem;

d=div(time,1000);
sec= d.quot;
ms = d.rem;

sprintf(outTime,"%02i:%02i:%02i,%03i",hour,min,sec,ms);

return outTime;


}
printTime(int time) {
printf("%s",timeToString(time));
}

int strTimeToInt(char str[13]) {
int hour,min,sec,ms,error;
int time;
char aux[4];

strncpy(aux,str,2);
aux[2]='\0';
hour = atoi(aux);

strncpy(aux,&str[3],2);
aux[2]='\0';
min = atoi(aux);

strncpy(aux,&str[6],2);
aux[2]='\0';
sec = atoi(aux);

strncpy(aux,&str[9],3);
aux[3]='\0';
ms = atoi(aux);

time= ms + 1000*sec + 1000*60*min + 1000*60*60*hour;

//printf("%i ",error);
//printf("( %02i:%02i:%02i,%03i )",hour,min,sec,ms);

return time;
}
getTime(char str[1024]) {
char str_time[13];
char end_time[13];

sscanf(str,"%s --> %s",str_time,end_time);
aux_start_time = strTimeToInt(str_time);
aux_end_time = strTimeToInt(end_time);

}
update_time(char str[1024]) {
getTime(str);

/* Apply sync. */
aux_start_time = abs((float)(aux_start_time * 100) / time_desync);
aux_end_time = abs((float)(aux_end_time * 100) / time_desync);

/* Apply pad */
aux_start_time = aux_start_time - gap;
aux_end_time = aux_end_time - gap;

printTime(aux_start_time);
printf(" --> ");
printTime(aux_end_time);
printf("%s",&str[29]);

}

isInteger(char str[1024]) {
int i=0;
while(i<(strlen(str)-2)) {
if(str[i]>47 && str[i]<58) {
i++;
} else {

return -1;
}
}
if(i==0) {
return -1;
} else {
return 0;
}
}

main(int argc, char *argv[]) {
char line[1024];
FILE *f;
int index,startIndex;
int sync_start_time,sync_end_time;

if (argc < 4) {

fprintf(stderr,"Subsincro 0.3 by Pron\n\n");

fprintf(stderr,"Usage: %s file.srt new_start_time new_end_time\n", argv[0]);

fprintf(stderr,"Time format: hh:mm:ss,mmm\n\n");

return 1;

}

if(strlen(argv[2])!=12 || strlen(argv[3])!=12) {
fprintf(stderr,"Time argument format have to be 00:00:00,000\n");

return 1;
}

new_start_time= strTimeToInt(argv[2]);
new_end_time=strTimeToInt(argv[3]);


if((f = fopen( argv[1], "r" ))==NULL) {
fprintf(stderr,"File '%s' not exist\n",argv[1]);
return 1;
}

while((fgets(line, 1024, f))!=NULL) {
if(isInteger(line)==0) {
index=atoi(line);
fgets(line, 1024, f);
getTime(line);
if(subIndex==1) {
startIndex=index;
old_start_time = aux_start_time;
}
subIndex++;
}
}
old_end_time = aux_start_time;

//time_desync = (old_end_time *100.0)/(old_end_time - ((old_end_time - old_start_time) - (new_end_time - new_start_time)));
time_desync = (((float)old_end_time - (float)old_start_time) * 100.0) / ((float)new_end_time - (float)new_start_time);


/* gap*/
sync_start_time = ((float)(old_start_time * 100) / time_desync);
sync_end_time = ((float)(old_end_time * 100) / time_desync);

gap = sync_start_time - new_start_time;

fprintf(stderr,"Desynchronization: %f\n",time_desync);


fprintf(stderr,"Sub. Index\tOld Time\tSub. Synchronized\n",timeToString(gap));
fprintf(stderr,"%i\t\t%s\t%s\n",startIndex,timeToString(old_start_time),timeToString(sync_start_time - gap));
fprintf(stderr,"[...]\n");
fprintf(stderr,"%i\t\t%s\t%s\n",index,timeToString(old_end_time),timeToString(sync_end_time - gap));
fseek(f,0,0);
subIndex=1;
while((fgets(line, 1024, f))!=NULL) {
if(isInteger(line)==0) {
printf("%s",line);
fgets(line, 1024, f);
update_time(line);
subIndex++;
} else {
printf("%s",line);
}
}
fclose(f);
return 0;
}
}