Advertisement
jacknpoe

Subtitle Tuning 0.3B (.srt)

Oct 7th, 2013
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.64 KB | None | 0 0
  1. //#########################################################################//
  2. //                                                                         //
  3. // Subtitle Tuning 0.3B (L) 2013 Ricardo Erick Rebêlo (jacknpoe)           //
  4. //                                                                         //
  5. // (.avis with .srt subtitle use: program <sourcefile> <targetfile> 0.9975 //
  6. //                                                                         //
  7. //#########################################################################//
  8.  
  9. #include <iostream>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <fstream>
  14. #include <cctype>
  15. #include <sstream>
  16. #include <locale.h>
  17.  
  18. using namespace std;
  19.  
  20. #define SPACER1 ":"
  21. #define SPACER2 ","
  22. #define AHUNDREDHOURS 360000000
  23. #define MAXFILENAME 256
  24. #define MAXLINESIZE 65536
  25. #define EXTENSION ".srt"
  26.  
  27. // *** time, value and convertion
  28. class cTimeConverter {
  29.    long mili_seconds;
  30.    char ample[ 13], ampleinsecure[ 13];
  31. protected:
  32.    void assemble_ample( void);
  33.    long ample_to_long( char *);
  34. public:
  35.    cTimeConverter( void) { mili_seconds = 0; assemble_ample(); };
  36.    cTimeConverter( char * p_value) { mili_seconds = ample_to_long( p_value); assemble_ample(); };
  37.    cTimeConverter( long   p_value) { mili_seconds = p_value; assemble_ample(); };
  38.    char * as_char( void) { return ampleinsecure; };
  39.    long   as_long( void) { return mili_seconds; };
  40.    void set_value( long   p_value) { mili_seconds = p_value; assemble_ample(); };
  41.    void set_value( char * p_value) { mili_seconds = ample_to_long( p_value); assemble_ample(); };
  42.     cTimeConverter operator=( cTimeConverter p_value) { mili_seconds = p_value.mili_seconds; assemble_ample(); return *this; }
  43.     cTimeConverter operator*=( double p_value) { mili_seconds *= p_value; assemble_ample(); return *this; };
  44.     cTimeConverter operator/=( double p_value) { mili_seconds /= p_value; assemble_ample(); return *this; };
  45. } oTimeConverter;
  46.  
  47. // *** assemble ample from miliseconds (error reduction with AHUNDREDHOURS)
  48. void cTimeConverter::assemble_ample( void) {
  49.     char hours[3], minutes[3], seconds[3], miliseconds[4]; int temp;
  50.     temp = mili_seconds % AHUNDREDHOURS;
  51.     snprintf( miliseconds, 4, "%03d", temp % 1000); temp /= 1000;
  52.     snprintf( seconds, 3, "%02d", temp % 60); temp /= 60;
  53.     snprintf( minutes, 3, "%02d", temp % 60); temp /= 60;
  54.     snprintf( hours, 3, "%02d", temp);
  55.  
  56.     strcpy( ample, hours); strcat( ample, SPACER1);
  57.     strcat( ample, minutes); strcat( ample, SPACER1);
  58.     strcat( ample, seconds); strcat( ample, SPACER2);
  59.     strcat( ample, miliseconds);  strcpy( ampleinsecure, ample);   
  60. }
  61.  
  62. // *** return miliseconds from ample (format error ignored)
  63. long cTimeConverter::ample_to_long( char * p_value) {
  64.     char hours[3], minutes[3], seconds[3], miliseconds[4];
  65.  
  66.     hours[0] = p_value[0];  hours[1] = p_value[1];  hours[2] = 0;
  67.     minutes[0] = p_value[3];  minutes[1] = p_value[4];  minutes[2] = 0;
  68.     seconds[0] = p_value[6];  seconds[1] = p_value[7];  seconds[2] = 0;
  69.     miliseconds[0] = p_value[9];  miliseconds[1] = p_value[10];  miliseconds[2] = p_value[11];  miliseconds[3] = 0;
  70.  
  71.     return ( ( atoi( hours) * 60 + atoi( minutes) ) * 60 + atoi( seconds) ) * 1000 + atoi( miliseconds) ;
  72. }
  73.  
  74. // *** open files, read data, call converstor, keep multiplier, save file
  75. class cSubtitleTuning {
  76.     ifstream oReadFile; ofstream oSaveFile; double multiplier;
  77.     char sReadFile[ MAXFILENAME], sSaveFile[ MAXFILENAME];
  78.     char sReadFilei[ MAXFILENAME], sSaveFilei[ MAXFILENAME];
  79. private:
  80.  
  81. // tolower in a string
  82.     void str_tolower( char * p_value, int maximum){
  83.         int iindex = 0;
  84.         while( p_value[ iindex] != 0 and iindex < maximum ){
  85.             p_value[ iindex] = tolower( p_value[ iindex]);
  86.             iindex++;
  87.         };
  88.     }
  89.  
  90. // normalize file names
  91.     void normalizename( char * cName){
  92.         int isize; char final[5];
  93.         isize = strlen( cName);
  94.         if( isize > 4)
  95.         {
  96.             strcpy( final, &cName[ isize-4]);
  97.             str_tolower( final, 4);
  98.             if( strcmp( final, EXTENSION) == 0) return;
  99.         }
  100.         strcat( cName, EXTENSION);
  101.     }
  102. public:
  103.  
  104.     cSubtitleTuning() { multiplier = 1; }
  105.  
  106. // get single multiplier parameter
  107.     bool set_multiplier( char * p_value ) {
  108.         return ( ( istringstream ( p_value) >> multiplier) and multiplier > 0);
  109.     }
  110.  
  111. // get compound multiplier parameters
  112.     bool set_multiplier( char * diference, char * base_time) {
  113.         long i_diference, i_base_time, isize;
  114.         char temp_ample[] = "0000000000000";
  115.         if( ( ! ( istringstream ( diference) >> i_diference)) or i_diference == 0) return false;
  116.         isize = strlen( base_time);
  117.         if( isize < 12) temp_ample[ 12 - isize] = 0; else temp_ample[ 0] = 0;
  118.         strcat( temp_ample, base_time);
  119.         oTimeConverter.set_value( temp_ample);
  120.         i_base_time = oTimeConverter.as_long();
  121.         if( ( i_base_time == 0) or ( i_base_time <= abs( i_diference) ) ) return false;
  122.         multiplier = ( double ( i_base_time) + double ( i_diference) ) / ( double ( i_base_time));
  123.         return true;
  124.     }
  125.  
  126. // open the read file
  127.     bool openreadfile( char * cName){
  128.         strcpy( sReadFile, cName);
  129.         normalizename( sReadFile);
  130.         strcpy( sReadFilei, sReadFile);
  131.         oReadFile.open( sReadFile, ios::in);
  132.         return oReadFile.is_open();
  133.     }
  134.  
  135. // open the write file
  136.     bool openwritefile( char * cName){
  137.         strcpy( sSaveFile, cName);
  138.         normalizename( sSaveFile);
  139.         strcpy( sSaveFilei, sSaveFile);
  140.         oSaveFile.open( sSaveFile, ios::out); //, ios::nocreate
  141.         return oSaveFile.is_open();
  142.     }
  143.  
  144. // changes the time of te lines with  -->
  145.     void recalculate( char * charLine){
  146.         char * cTimeConverter1, * cTimeConverter2, * cBetween;
  147.        
  148.         cTimeConverter1 = strtok( charLine, " \t" );
  149.         cBetween  = strtok( NULL, " \t" );
  150.         cTimeConverter2 = strtok( NULL, " \t" );
  151.  
  152.         // CORE OF THE CHANGES IN THE FILE IN THE FOUR LINES BELOW
  153.         oTimeConverter.set_value( cTimeConverter1); oTimeConverter *= multiplier; cTimeConverter1 = oTimeConverter.as_char();
  154.         strcpy( charLine, cTimeConverter1); strcat( charLine, " --> ");
  155.         oTimeConverter.set_value( cTimeConverter2); oTimeConverter *= multiplier; cTimeConverter2 = oTimeConverter.as_char();
  156.         strcat( charLine, cTimeConverter2);
  157.     }
  158.    
  159.     char * get_sReadFile( void) { return sReadFilei; };
  160.  
  161.     char * get_sSaveFile( void) { return sSaveFilei; };
  162.  
  163. // read from a file and write in other (selecting lines with --> to changes
  164.     bool process( void){
  165.         char sTeste[ MAXLINESIZE];
  166.         while( ! oReadFile.eof() ) {
  167.             oReadFile.getline( sTeste, MAXLINESIZE-1);
  168.             if( strstr( sTeste, " --> ") != NULL) recalculate( sTeste);
  169.             oSaveFile << sTeste << "\n";
  170.             if( oSaveFile.bad() or oSaveFile.fail()) return false;
  171.         }
  172.         return true;
  173.     }
  174.  
  175.     ~cSubtitleTuning() {
  176.         if( oReadFile.is_open() ) oReadFile.close();
  177.         if( oSaveFile.is_open() ) oSaveFile.close();
  178.     }
  179.  
  180. } oSubtitleTuning;
  181.  
  182. // *** centralize all messagens and dialogs
  183. class cMessage {
  184.     char programname[ MAXFILENAME];
  185.  
  186. public:
  187.  
  188. // help (insufficient parameters)
  189.     void help( void) {
  190.         cout << "\nSubtitle Tuning 0.3B (L) 2013 Ricardo Erick Rebêlo (jacknpoe)";
  191.         cout << "\n\nSyntaxes: 1. " << programname << " <source> <target> <variation> <base time>";
  192.         cout << "\n          2. " << programname << " <source> <target> <multiplier>";
  193.         cout << "\n\nsource: the file must exist, in the " << EXTENSION << " format, free from errors.";
  194.         cout << "\ntarget: " << EXTENSION << " file, can't be the source file. It will be overwritten.";
  195.         cout << "\nvariaton: milisseconds to apply to base time (to calculate the rate of change).";
  196.         cout << "\n          (if negative will advance, if positive delay the subtitles)";
  197.         cout << "\nbase time: time (HH:MM:SS,mmm) to apply 100% of the variation.";
  198.         cout << "\nmultiplier: positive non-integer number to multiply the subtitles time.";
  199.         cout << "\n\nExamples:";
  200.         cout << "\n\n1. " << programname << " test1 test2 -9750 00:50:30,000";
  201.         cout << "\n   adjusts the time gradually until, in fifty minutes of video, the subtitle";
  202.         cout << "\n   is advanced 9,75 seconds (approximately 99,6782% of the time)";
  203.         cout << "\n\n2. " << programname << " test1 test2 0.9975     (standard to some .avi files)";
  204.         cout << "\n   adjust the subtitles in test1" << EXTENSION << " in 99,75% of time and write in test2" << EXTENSION << ".\n";
  205.     }
  206.  
  207. // find the program name, without extension and path
  208.     void set_programname( char * executable){
  209.         int iBegin = 0, iEnd = 0, iindex;
  210.         for( iindex = strlen( executable)-1; iindex >= 0 and iBegin == 0; iindex-- ) {
  211.             if( executable[iindex] == '.' and iEnd == 0)    iEnd = iindex - 1;
  212.             if( iEnd != 0 and iBegin == 0 and
  213.                 ( executable[iindex] == '\\' or executable[iindex] == '/' or executable[iindex] == '>' ) )
  214.                     iBegin = iindex + 1;
  215.         }
  216.         if( iEnd != 0 and iBegin <= iEnd )  {  
  217.             strcpy( programname, &executable[ iBegin]);
  218.             programname[iEnd-iBegin+1] = 0;
  219.         } else if ( iEnd == 0 and iBegin == 0 ) strcpy( programname, executable);
  220.           else strcpy( programname, "undetermined");
  221.  
  222.     }
  223.  
  224. // some errors and messages (self explanatory)
  225.     void error_multiplier( char * p_value) {
  226.         cout << "\nInvalid '" << p_value << "' parameter (must be numeric greater than zero).\n";
  227.     }
  228.  
  229.     void error_multiplier( char * diference, char * base_time) {
  230.         cout << "\nInvalid parameters: '" << diference << "' and/or '"<< base_time << "'.\n";
  231.     }
  232.  
  233.     void error_opening( void){
  234.         cout << "\nFile " << oSubtitleTuning.get_sReadFile() << " cannot be opened.\n";
  235.     }
  236.  
  237.     void error_openwrite( void){
  238.         cout << "\nFile " << oSubtitleTuning.get_sSaveFile() << " cannot be opened or created.\n";
  239.     }
  240.  
  241.     void error_process( void){
  242.         cout << "\nAn error occurred in the process of creating of file " << oSubtitleTuning.get_sSaveFile() << ".\n";
  243.     }
  244.  
  245.     void processing( void){
  246.         cout << "\nProcessing file " << oSubtitleTuning.get_sSaveFile() << "...\n";
  247.     }
  248.  
  249.     void sucess( void){
  250.         cout << "\nFile " << oSubtitleTuning.get_sSaveFile() << " was successfully generated.\n";
  251.     }
  252. } oMessage;
  253.  
  254.  
  255. // ***  M A I N  () *******************************************************************
  256.  
  257. int main( int argc, char* argv[]) {
  258.     setlocale( LC_ALL, "");     // equal caracters in prompt
  259.  
  260.     oMessage.set_programname( argv[ 0]);
  261.  
  262.     if( argc < 4) { oMessage.help(); exit( 1); };
  263.  
  264.     if( argc == 4) if( ! oSubtitleTuning.set_multiplier( argv[ 3]) )
  265.                                             { oMessage.error_multiplier( argv[ 3]); exit( 2); }
  266.  
  267.     if( argc == 5) if( ! oSubtitleTuning.set_multiplier( argv[ 3], argv[ 4]) )
  268.                                             { oMessage.error_multiplier( argv[ 3], argv[ 4]); exit( 3); }
  269.  
  270.     if( ! oSubtitleTuning.openreadfile( argv[ 1]) ) { oMessage.error_opening(); exit( 4); }
  271.  
  272.     if( ! oSubtitleTuning.openwritefile( argv[ 2]) ) { oMessage.error_openwrite(); exit( 5); }
  273.  
  274.     oMessage.processing(); if( ! oSubtitleTuning.process() ) { oMessage.error_process(); exit( 6); }
  275.  
  276.     oMessage.sucess();  return EXIT_SUCCESS;
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement