Ajustando o sincronismo da legenda com o filme

Publicado por Geraldo José Ferreira Chagas Júnior 26/08/2008

[ Hits: 10.444 ]

Homepage: http://prginfo.blogspot.com

Download sincronizalegenda.c




Estava com problema da legenda (srt) começar em tempo diferente do vídeo. Não achei um programa para fazer o ajuste e sim uma dica usando o OpenOffice.

Resolvi então fazer esse programa para resolver meu problema e resolvi postar.

  



Esconder código-fonte

/*
   Programa para sincronização de legendas no formato srt.
   Por: Geraldo José Ferreira Chagas Júnior
   20/07/2008
   compilador: gcc - GNU/Linux
  
   O programa utiliza o ajuste passado como parâmetro para
   sincronizar a legenda dos filmes. são aceitos valores negativos
   e positivos em milisegundos.

   exemplo: Se a legenda estiver com atrazo de 1 min e 2,345 s 
   será utilizado um ajuste de - (1*60*1000) + (2 * 1000) + 345 = -62345

   O código pode ser usado, distribuído e melhorado sem nenhuma restrição.
   Peço que em caso de meloras, me envie a melhoria para que eu tenha também.
   gjr_rj@msn.com
*/

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

const int TAMLINHA=256;

long strToMili (char* str);
void miliToStr (long mili, char* str);

int main (int argc, char* argv[])
{
   char opc;
   char* arqOri;
   char* arqDest;
   long  ajust;

   FILE* fOri;
   FILE* fDest;

   long tamArq;

   /* esse jogo com as duas variáveis de percentual servira para não ficar
      imprimindo o percentual o tempo todo, caso não tenha mudado*/
   int  percent;
   int  percentAnt=-1;

   char linha [TAMLINHA];
   char temp [20];

   char* sub;
   int pos;

   if (argc != 4)
   {
      printf ("Os parâmetros são:\n");
      printf ("1 - Arquivo a ser convertido\n");
      printf ("2 - Ajuste da sincronização em milisegundos\n");
      printf ("3 - Arquivo sincronizado\n");
      return 0;
   }
   
   arqOri  = argv[1];
   arqDest = argv[3];
   ajust   = atoi (argv[2]);

   
   if (!(fOri=fopen(arqOri, "r")))
   {
      printf ("Erro na abertura do arquivo de origem !\n");
      return 0;
   }

   if ((fDest=fopen(arqDest, "r")))
   {
      close (fDest);
      printf ("O aquivo de destino %s já existe. Deseja substitui-lo (s/n) ? ", arqDest);
      opc = getchar();
      if ((opc!='S') && (opc!='s')) exit (0);
   }
      
   if (!(fDest=fopen(arqDest, "w+")))
   {
      printf ("Erro na abertura do arquivo de destino !\n");
      return 0;
   }

   /* pegando o tamanho do arquivo de origem para imprimir a porcentagem */
   fseek (fOri, 0, SEEK_END);
   tamArq = ftell (fOri);
   /* voltando ao inicio do arquivo */
   fseek (fOri, 0, SEEK_SET);

   printf ("0 %c convertido.",'%');
   while (fgets (linha, TAMLINHA, fOri))
   {    
            
      if (sub=strstr(linha," --> "))
      {
         pos = sub - &linha[0];
         strcpy (temp, &linha[pos+5]);
         miliToStr (strToMili (linha)+ajust, linha);
         miliToStr (strToMili (temp)+ajust, temp);
         strcat (linha, " --> ");
         strcat (linha, temp);
         strcat (linha, "\n");
      }

      fputs (linha, fDest);

      
      percent = ftell (fOri) * 100 / tamArq;

      if (percent!=percentAnt)
      { 
         printf ("\r%d %c convertido.",percent,'%');
         percentAnt=percent;
      }
   }

   printf("\n");
   close (fOri);
   close (fDest);
}

long strToMili (char* str)
{
   char temp[10];
   long h;
   long m;
   long s;

   int i=0;
   int j=0;
   
   while (str[i]!='{FONTE}')
   {
      if ((str[i]==' ') || (str[i]==':')) break;
      temp[j++]=str[i++];
   }
   
   temp[j]='{FONTE}';
   h=atoi(temp) * 60 * 60 * 1000;
   if (str[i]!='{FONTE}')
   {
      i++;
      j=0;
   }

   while (str[i]!='{FONTE}')
   {
      if ((str[i]==' ') || (str[i]==':')) break;
      temp[j++]=str[i++];
   }
   
   temp[j]='{FONTE}';
   m=atoi(temp) * 60 * 1000;

   if (str[i]!='{FONTE}')
   {
      i++;
      j=0;
   }

   while (str[i]!='{FONTE}')
   {
      if ((str[i]==' ') || (str[i]==':') || (str[i]==',')) break;
      temp[j++]=str[i++];
   }
   
   temp[j]='{FONTE}';
   s=atoi(temp) * 1000;

   if (str[i]!='{FONTE}')
   {
      i++;
      j=0;
   }

   while (str[i]!='{FONTE}')
   {
      if (str[i]==' ') break;
      temp[j++]=str[i++];
   }
   
   temp[j]='{FONTE}';
   return  (h + m + s + atoi(temp));
}

void miliToStr (long mili, char* str)
{
   char temp[20];
   long h;
   long m;
   long s;
   int i;

   h = (mili - (mili % 3600000)) / 3600000;
   mili = mili-(h*3600000);

   m = (mili - (mili % 60000)) / 60000;
   mili = mili-(m*60000);

   s = (mili - (mili % 1000)) / 1000;
   mili = mili-(s*1000);

   snprintf(str,20,"%2d:%2d:%2d,%3d", h, m , s, mili);
   for (i=0;str[i]!='{FONTE}';i++)
   {
      if (str[0]==' ') 
         str[0]='0';
      else if ((str[i]==' ') && (str[i-1] != '>') && (str[i+1] != '-'))
         str[i]='0';

   }
    
}

Scripts recomendados

Ler string de um ficheiro

dog - semelhante ao cat do Linux

leitura/escrita de dados/estruturas em arquivo

Logger

Programinha que busca arquivos


  

Comentários
[1] Comentário enviado por mslomp em 30/08/2008 - 18:09h

cara, parabéns. isso vai salvar a vida de muita gente... hoje mesmo passei uma trabalheira dos infernos para sincronizar uma legenda. para piorar, a legenda era dividida em duas partes, e o vídeo em si era um só. tive que recorrer ao SubtitleWorkshop (Windows), e ainda assim muita coisa teve que ser manual. sincroniza aqui, dessincroniza acolá. não foi fácil, e infelizmente só agora achei - e por acaso - esse seu código aqui no vol dando sopa.

apenas como um adendo: encontrei um tal Subtitle Editor para Linux. não testei, mas analisando por cima as features parece ser bom:
http://home.gna.org/subtitleeditor

[2] Comentário enviado por removido em 19/02/2009 - 15:31h

Eu uso Kaffeine e fiz um "ajuste" utilizando os atalhos de teclado:

Control + Alt + Right (atrasar)
Control + Alt + Left (adiantar)

[3] Comentário enviado por DeuRuimDotCom em 27/06/2019 - 21:47h

Muito bom mesmo. Tive essa mesma idéia, comecei o projeto mas por falta de tempo ainda não o concluí.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts