Modifier les sous titres. [linux]

Soyez le premier à donner votre avis sur cette source.

Vue 10 433 fois - Téléchargée 164 fois

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

Ajouter un commentaire Commentaires
Messages postés
1
Date d'inscription
mardi 6 novembre 2007
Statut
Membre
Dernière intervention
22 novembre 2007

Bonjour à tous.

Je débarque un peu au hasard pour tout vous dire... et je ne suis pas du tout trempé dans la programmation.

J'ai effectivement pas mal de fichiers .srt en décalage, souvent de 2 à 5 secondes; et pour que je comprenne bien, tout ce qu'il y a au dessus n'est absolument pas abordable pour un newbie comme moi... ? navré si je dérange, je recherche juste un petit programme tout simple qui permette de décaler les sous titres, et gogole m'a envoyé ici...

Mais je comprends qu'à moins d'être un programmeur, il n'y a aucune solution... hu?!

bonne route
Messages postés
1221
Date d'inscription
jeudi 23 août 2001
Statut
Membre
Dernière intervention
9 septembre 2018

D'autant plus que, pour ce qui est du DotNet, c'est très facile de vérifier l'implémentation via Reflector : cet outil gratuit permet de voir le code pré-assembleur MSIL désassemblé dans le langage de ton choix, donc de vérifier les optimisations du compilateur.
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
14
Bon là, je vais reformuler tout ça, car j'ai fais plein d'erreurs:

Mic32768 >> Mon exemple est très bien structuré. Aussi, je n'est jamais vue de compilateur refuser l'optimisation parce qu'il y a un jmp volontairement ajouté dans le code.

Pour le reste, BruNews a totalement raison. Il ne faut pas croire
sur parole tout ce qui sort de la bouche des "grands" programmeurs. Il faut aussi se baser sur sa déduction et sur le résultat (le listing par exemple). Si tu trouve que les goto n'ont pas leur place, c'est que tu ne sais pas où et comment bien les utiliser tout simplement, car les goto on leur raison d'être (je ne crois pas que Ritchie les aient intégrés au langage pour rien).

Il peut, en effet, exister un moyen de se passer des goto. Cependant, on peut générer une structure de code bien plus difficile à lire et voir même à coder.
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
14
Bon d'accord, mon exemple n'est peut-être pas si dur changer car il est extrêmement basique:
void fonction (...)
{
...
if(x) {
...
if(y) {
...
}
fclose(file);
}
free(mem);
}

N'empêche que sur des codes légèrement plus complexes, on ne peut pas utiliser cette méthode sans dupliquer des morceaux de codes et aussi rendre le code très compliqué à lire et très peu "élégant".
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
14
Mic32768 >> Mon exemple est parfaitement structuré et je n'est jamais vue de compilateur refuser l'optimisation parce qu'il y a un jmp volontairement ajouté dans le code. Je serais curieux de voir comment tu peux reproduire l'exemple que j'ai donné plus haut avec ta soi-disent programmation structuré et optimisé.
Pour le reste, BruNews a totalement raison. Il ne faut pas croire tout ce qui sort de la bouche de ces "programmeurs". Si tu trouve que les goto n'ont pas leurs place, c'est que tu ne sais pas les utiliser tout simplement.
Afficher les 22 commentaires

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.