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

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

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.