[devc++] splitter de fichier .srt (sous-titres)

Soyez le premier à donner votre avis sur cette source.

Vue 38 540 fois - Téléchargée 837 fois

Description

Si vous avez un fichier .srt pour un divx, mais que celui-ci n'est prévu que pour un CD, alors que vous avez ce dit film en deux parties. Vous pouvez grace a ce petit logiciel séparer le fichier .srt en deux (ou plus) sans tout réecrire.

Pour ce faire, il vous faut tout d'abord (manuellement) couper votre fichier .srt en deux ou plus à l'endroit de votre choix (facile a faire avec le bloc note tout de meme, mon fichier ne fait que corriger les time-stamps, et les numero de sous-titres)! /!\\ attention la première ligne du fichier doit etre un numero de sous-titre !!
avec les deux fichiers .srt que vous obtenez, normalement la première partie n'a pas besoin de correction, le début des sous-titres est bien synchro avec le début du film. Par contre la deuxème partie ne l'est pas et c'est la qu'agit mon prog.

Syntaxe : srtsplit.exe in.srt [out.srt] [correct_offset_en_milisecondes]

correct_offset permet de décaler le début du sous-titre de + ou - quelques milisecondes

dans le zip je fourni un fichier .srt
ainsi que l'exe

Source / Exemple :


#include <stdlib.h>
#include <stdio.h>
#include <string.h> // stricmp () ; atoi ()
#include <ctype.h>  // isdigit ()
#include <math.h>   // floor ()

int correctoff = 0; // offset de correction en milisecondes

using namespace std;

// la chaine contient-elle un nombre ?
int isnum (char *test)
{
    for (int i=0; i < strlen(test); i++)
        if (!isdigit(test[i]) && (test[i] != '\\r') && (test[i] != '\\n') )
            return 0; // non retourne 0
    return 1; // oui retourne 1
}

// rajoute ou enleve quelque milisecondes
// pour caller la deuxième partie des sous-titres
// par rapport au début du deuxième cd
int correctoffset (int &milis, int &secondes, int &minutes, int &heures)
{
    milis += correctoff;
    if (milis >= 1000)
    {
        milis -= 1000;
        secondes++;
        if (secondes >= 60)
        {
            secondes -= 60;
            minutes++;
            if (minutes >= 60)
            {
                minutes -= 60;
                heures++;
            }
        }
    }
    return 0;
}

// corrige les time-stamps (remet a 00:00:00 le premier sous-titre
// et décale d'autant les suivants
int reTime (char *Data)
{
    static int offsettime = 0;
    int heures, minutes, secondes, milis;
    int heures2, minutes2, secondes2, milis2;
    int tmpensec;

    sscanf (Data, "%d:%d:%d,%d --> %d:%d:%d,%d",
                    &heures, &minutes, &secondes, &milis,
                    &heures2, &minutes2, &secondes2, &milis2 );

    // partie 1
    // met tout en secondes
    tmpensec = heures * 3600 + minutes * 60 + secondes;
    if (offsettime == 0)
        offsettime = tmpensec;

    // puis décale de 'offsettime' secondes
    tmpensec -= offsettime;

    // repasse en format hh:mm:ss
    heures = (int)floor(tmpensec/3600);
    tmpensec -= heures*3600;
    minutes = (int)floor(tmpensec/60);
    tmpensec -= minutes*60;
    secondes = tmpensec;

    // offset rajouter par l'utilisateur par la ligne de commande
    correctoffset (milis, secondes, minutes, heures);

    // partie 2
    tmpensec = heures2 * 3600 + minutes2 * 60 + secondes2;
    tmpensec -= offsettime;

    heures2 = (int)floor(tmpensec/3600);
    tmpensec -= heures2*3600;
    minutes2 = (int)floor(tmpensec/60);
    tmpensec -= minutes2*60;
    secondes2 = tmpensec;

    correctoffset (milis2, secondes2, minutes2, heures2);

    // Place la chaine corrigée dans Data
    sprintf(Data, "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\\r\\n",
                    heures, minutes, secondes, milis,
                    heures2, minutes2, secondes2, milis2 );

    return 0;
}

int main(int argc, char *argv[])
{
    FILE *fich1, *fich2;
    int numligne, offsetdeb, step = 1;
    char Buffer[255], fichierout[255];
    char *Data;
    
    switch (argc) // Extrait les arguments de la ligne de commande
    {
        case 2:
            strcpy (fichierout, "out.srt");
            break;
        case 3:
            if (isnum (argv[2]))
            {
                correctoff = atoi (argv[2]);
                strcpy (fichierout, "out.srt");
            }
            else
                strcpy (fichierout, argv[2]);
            break;
        case 4:
            if (isnum (argv[3]) && !isnum (argv[2]))
            {
                correctoff = atoi (argv[3]);
                strcpy (fichierout, argv[2]);
                break;
            }
        case 1:
        default:
            printf ("Syntaxe : srtsplit.exe in.srt [out.srt] [correct_offset_en_milisecondes]\\n");
            system ("PAUSE");
            return 0;                
    }
    
    // Ouvre les fichiers
    if ((fich1 = fopen(argv[1], "rb")) == NULL) // r : lecture ; b : mode binaire
    {
        printf ("Erreur à l'ouverture du fichier %s\\n", argv[1]);
        system ("PAUSE");
        return 0;
    }
    
    if ((fich2 = fopen(fichierout, "w+b")) == NULL) // w+ : écrase le fichier si il existe
    {
        printf ("Erreur à l'ouverture du fichier %s\\n", fichierout);
        system ("PAUSE");
        return 0;
    }

    // lit le premier numero de sous-titre, et l'enregistre comme référence
    Data = fgets (Buffer, 255, fich1);
    if (isnum (Data))
        offsetdeb = atoi (Data) - 1;

    // lit ligne par ligne jusqu'a la fin
    while (!feof(fich1))
    {
        if (stricmp (Data, "\\r\\n"))
            switch (step) // De quel type de ligne s'agit-il ?
            {
                case 1: // numero de ligne
                    if (isnum (Data))
                    {
                        numligne = atoi (Data);
                        // Soustrais le numero de sous-titre
                        // par rapport à la référence
                        // (on pourrait aussi simplement incrementer une variable
                        //  ca serait trop facile non ? :) )
                        sprintf(Data, "%d\\r\\n", numligne - offsetdeb);
                        // Enregistre
                        fputs (Data, fich2);
                        step++;
                    }
                    else // si la ligne lu n'est pas un nombre
                        fputs (Data, fich2);
                    break;

                case 2: // time stamp
                    reTime (Data); // corrige les time-stamp
                    fputs (Data, fich2);
                    step++;
                    break;

                case 3: // sous-titre
                    fputs (Data, fich2);
                    break;
            }
        else // sous-titre ou espace vide
        {
            fputs (Data, fich2);
            step = 1;
        }

        Data = fgets (Buffer, 255, fich1); // Lit une ligne
    } // Fin while()
     
    // ferme les fichiers
    fclose(fich1);
    fclose(fich2);

    printf ("Traitement terminé avec succès\\n");
    system ("PAUSE");
    return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// edit 5 mai 2005 :

// j'ai fais la meme chose en awk sous linux :

/^[0-9]+[\n\r]?$/ { print $0 ; ligne = $1}

/^[0-9]+[:]+/ {
	FS = "[:, ]+"
	
	offset = -4
	debut = 0

	if (ligne >= debut) {
		h1=$1; m1 = $2; s1 = $3
		h2=$6; m2 = $7; s2 = $8

		s1 += offset
		s2 += offset

		if (s1 >= 60) {
			m1++
			s1 -= 60
		}
		if (m1 >= 60) {
			h1++
			m1 -= 60
		}

		if (s2 >= 60) {
			m2++
			s2 -= 60
		}
		if (m2 >= 60) {
			h2++
			m2 -= 60
		}

		printf("%02i:%02i:%02i,%03i --> %02i:%02i:%02i,%03i\n", $1, m1, s1, $4, $6, m2, s2, $9)
	} else {
		print $0
	}

	getline
	while ($0 !~ /^[ \n\r]*$/) {
		print $0
		getline
	}
	print $0
}

// c'est plus petit, et tout aussi éfficace
// il suffit de modifier les paramètres offset (en secondes) et debut (0 pour modifier a partir de la première ligne)

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
37
Date d'inscription
jeudi 27 mars 2003
Statut
Membre
Dernière intervention
6 mai 2005

Tout à fait, il faut le compiler soit même, mais ça ne devrait pas poser de problème particulier. Je peux te conseiller un compilateur gratuit : bloodshed dev cpp
Messages postés
1
Date d'inscription
samedi 20 septembre 2008
Statut
Membre
Dernière intervention
20 septembre 2008

est il normal qu'il manque le fichier exe dans le zip car le je vois pas bien comment utiliser le programme
Messages postés
37
Date d'inscription
jeudi 27 mars 2003
Statut
Membre
Dernière intervention
6 mai 2005

Vas y, si tu as le courage... Moi j'ai pas trop le temps ^^
Messages postés
780
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
16 avril 2009
1
"+ ou - quelques milisecondes"

Ce serait bien de pouvoir le déplacer de quelques minutes et tout :)
Enfin si t'as pas le temps, je me ferai un plaisir de le faire en vc++ 6 win32
Messages postés
780
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
16 avril 2009
1
héhé, AntiTrust ce fut mon deuxième DivX, je l'avais vu 6 mois avant sa sortie fr, et j'avais adoré
Afficher les 13 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.