Modifier les sous titres. [linux]

Description

Le but est tout simple, il s'agit de décaler les fichiers de sous titres (.srt) en les décalant de tant de secondes ou de millisecondes.
J'ai codé ça parce que ça m'arrive souvent d'avoir un fichier décalé d'une demie seconde et c'est assez rageant :)
C'est sur que c'est parfois assez long et que le code pourrait etre optimisé mais bon ça suffit..

Un fichier srt est de cette forme :

Numéro des sous titres
xx:xx:xx,xxx --> xx:xx:xx,xxx
Sous titres

Ce programme cherche les expressions de temps (00:02:31,699) et les modifie

Source / Exemple :


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

#define M 1000

int verifcmd(int argc, char *argv[]) //Vérification de la ligne de commande
{
	FILE* F;
	int i, s;
	
		if( (F=fopen(argv[1],"r")) != NULL) //Test du fichier
		{
			s=strlen(argv[2]);
			for(i=0;i<s;i++) //Test du nombre de seconde. argv[2] doit composé de chiffres avec peut etre le signe '-' en premier caractere
			{
				if( !isdigit(argv[2][i]) ) 
				{
					if(i==0 && argv[2][i]=='-')
						;
					else
					{
						printf("Le nombre de secondes est errone.\n");
						return 0;
					}
				}
			}
			if(argc==4) //On teste le nombre de millisecondes s'il ce parametre existe
			{
				s=strlen(argv[3]);
				for(i=0;i<s;i++)
				{
					if( !isdigit(argv[3][i]) )
					{
						if(i==0 && argv[3][i]=='-')
						;
						else
						{
							printf("Le nombre de millisecondes est errone.\n");
							return 0;
						}
					}
				}
			}
		}
		else
		{
			printf("Le fichier est introuvable.\n");
			return 0;
		}
	return 1;
}

char decalage(FILE* F, int n) //Effectue un placement précis dans une variable FILE *, n étant le nombre de caractere
{
	FILE *FN=F;
	char c;
	int i=0;
	
	if(n==0)
		return 0;
	
	for(i=0;i<n;i++)
		fscanf(FN,"%c", &c);
	return c;
}

int ligne(FILE *F1, int n) //Test si la l'expression qui suit est de la forme xx:xx:xx,xxx pour pouvoir la modifier
{
	if(decalage(F1,3)==':' && decalage(F1,3)==':' && decalage(F1,3) == ',')
	{
		rewind(F1);
		decalage(F1,n);
		return 1;
	}
	rewind(F1);
	decalage(F1,n);
	return 0;
};	

int dix(int x)
{
	int i=0, n=1;
	for(i=0;i<x;i++)
		n*=10;
	
	return n;
}
	

int ctoi(char* t, int n) //Transforme un char* en entier
{
	int i, x=0;
	
	for(i=0;i<n;i++)
		x=x+dix(i)*(t[i]-48);
		
	return x;
}

void itoc(int x, char* t) //Transforme un in en char*
{
	int temp;
	
	temp=x/100;
	t[0]=temp+48;
	x=x-temp*100;
	temp=x/10;
	t[1]=temp+48;
	x=x-temp*10;
	t[2]=x+48;
	
	return;
}

void temps(char* expression, int sec, int mil) //Fonction qui ajoute ou supprime du temps
{
	int m, p1, p2, p3; //Dans un fichier sous titres, un temps est de la forme p3:p2:p1,m
	char t[3];
	
	int temp,temp2;
	
	t[0]=expression[11];
	t[1]=expression[10];
	t[2]=expression[9];
	m=ctoi(t,3);
	
	t[0]=expression[7];
	t[1]=expression[6];
	p1=ctoi(t,2);
	
	t[0]=expression[4];
	t[1]=expression[3];
	p2=ctoi(t,2);
	
	t[0]=expression[1];
	t[1]=expression[0];
	p3=ctoi(t,2);
	
	//Algorithme 
	
	temp=m+p1*M+p2*M*60+p3*M*3600+mil+sec*M; //temp étant le temps total exprimé en millisecondes
	
	if(temp<=0)
		temp=0;
	
	p3=temp/(M*3600); //Ensuite on convertit ce temps dans les variables p3, p2, p1 et m
	temp2=p3*M*3600;
	temp-=temp2;
	
	p2=temp/(M*60);
	temp2=p2*M*60;
	temp-=temp2;
	
	p1=temp/M;
	temp2=p1*M;
	temp-=temp2;
	
	m=temp;
	
	//Fin de l'Algorithme
		
	itoc(m,t); expression[9]=t[0]; expression[10]=t[1]; expression[11]=t[2];
	itoc(p1,t); expression[6]=t[1]; expression[7]=t[2];
	itoc(p2,t); expression[3]=t[1]; expression[4]=t[2];
	itoc(p3,t); expression[0]=t[1]; expression[1]=t[2];
		
	return;
}

void srt(int argc, char *argv[]) //Fonction principale qui va lire un fichier caractere par caractere
{
	FILE *F1, *F2;
	int sec, mil;
	int i, n=1; //n étant le compteur de F1
	int cst=1, st;
	
	char c;
	char expression[12];
		
	sec=atoi(argv[2]);
	if(argc==4)
		mil=atoi(argv[3]);
	else
		mil=0;
	
	if(sec==0 && mil==0)
		return;
	
	if( (F1=fopen(argv[1],"r")) == NULL)
	{
		printf("Le fichier est introuvable.\n");
		return;
	}
	if( (F2=fopen("temporaire","w")) == NULL)
	{
		printf("Erreur lors de la creation du fichier temporaire.\n");
		return;
	}
	
	while(fscanf(F1,"%c", &c)!=EOF) //Traitement caractere par caractere
	{
		
		if(c=='\n'&&ligne(F1, n)) 
		{
			fprintf(F2,"\n"); n++;
			//Premiere partie
			
			for(i=0;i<12;i++)
			{
				fscanf(F1,"%c", &c);
				expression[i]=c;
			}n+=12;
			
			temps(expression,sec, mil);
			
			for(i=0;i<12;i++)
				fprintf(F2,"%c",expression[i]);
			
			//Seconde partie
			for(i=0;i<5;i++)
			{
				fscanf(F1,"%c", &c);
				fprintf(F2,"%c",c);
			} n+=5;	
			
			for(i=0;i<12;i++)
			{
				fscanf(F1,"%c", &c);
				expression[i]=c;
			}n+=12;
			
			temps(expression,sec, mil);
			
			for(i=0;i<12;i++)
				fprintf(F2,"%c",expression[i]);
			
		}
		else
		{
			n++;
			fprintf(F2,"%c",c);
		}
			
	}

	return;
}
void help() //Fonction d'aide
{
	printf("srt fichier secondes (millisecondes)\n\n");
	printf("exemples : \n");
	printf("$ srt sous-titres.srt 5 : Avance les sous titres de 5 secondes.\n");
	printf("$ srt sous-titres.srt -1 -500 : Recule les sous titres d'une seconde et demi.\n");
	
	return;
}

int main(int argc, char *argv[])
{
	char* nom; //Nom du fichier en ajoutant "old_" devant
	int i;
	
	if(argc>1)
	{
		nom=malloc(  strlen(argv[1]) +4*sizeof(char) );
	
		for(i=0;i<strlen(argv[1]);i++)
			nom[i+4]=argv[1][i];
		nom[0]='o';
		nom[1]='l';
		nom[2]='d';
		nom[3]='_';
	}
	
	if(argc==1)
		printf("Veuillez specifier une option. srt -help pour plus d'informations.\n");
	else if(argc==2)
	{
		if(strcmp(argv[1],"-help") == 0)
		{
			help();
		}
	}			
	else if(argc==3 || argc==4)
	{
		if(verifcmd(argc, argv)) //On vérifie la ligne de commande
		{
			srt(argc, argv); //Fonction de traitement
		}
	}

	rename(argv[1],nom);
	rename("temporaire", argv[1]);
	
	return 0;
}

Conclusion :


Ecrivez moi si vous avez des remarques, des suggestions a faire pour améliorer le programme ou pour ajouter de nouvelles fonctions.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.