📄 subtitle.c
字号:
} else { int i_layer = ( p_sys->i_type == SUB_TYPE_ASS ) ? atoi( temp ) : 0; /* ReadOrder, Layer, %s(rest of fields) */ snprintf( temp, sizeof(temp), "%d,%d,", i_idx, i_layer ); memmove( psz_text + strlen(temp), psz_text, strlen(psz_text)+1 ); memcpy( psz_text, temp, strlen(temp) ); } p_subtitle->i_start = ( (int64_t)h1 * 3600*1000 + (int64_t)m1 * 60*1000 + (int64_t)s1 * 1000 + (int64_t)c1 * 10 ) * 1000; p_subtitle->i_stop = ( (int64_t)h2 * 3600*1000 + (int64_t)m2 * 60*1000 + (int64_t)s2 * 1000 + (int64_t)c2 * 10 ) * 1000; p_subtitle->psz_text = psz_text; return VLC_SUCCESS; } free( psz_text ); /* All the other stuff we add to the header field */ if( !p_sys->psz_header ) p_sys->psz_header = strdup( "" ); if( !p_sys->psz_header ) return VLC_ENOMEM; p_sys->psz_header = realloc( p_sys->psz_header, strlen( p_sys->psz_header ) + strlen( s ) + 2 ); strcat( p_sys->psz_header, s ); strcat( p_sys->psz_header, "\n" ); }}/* ParseVplayer * Format * h:m:s:Line1|Line2|Line3.... * or * h:m:s Line1|Line2|Line3.... */static int ParseVplayer( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ){ VLC_UNUSED( i_idx ); demux_sys_t *p_sys = p_demux->p_sys; text_t *txt = &p_sys->txt; char *psz_text; int i; for( ;; ) { const char *s = TextGetLine( txt ); int h1, m1, s1; if( !s ) return VLC_EGENERIC; psz_text = malloc( strlen( s ) + 1 ); if( !psz_text ) return VLC_ENOMEM; if( sscanf( s, "%d:%d:%d%*c%[^\r\n]", &h1, &m1, &s1, psz_text ) == 4 ) { p_subtitle->i_start = ( (int64_t)h1 * 3600*1000 + (int64_t)m1 * 60*1000 + (int64_t)s1 * 1000 ) * 1000; p_subtitle->i_stop = 0; break; } free( psz_text ); } /* replace | by \n */ for( i = 0; psz_text[i] != '\0'; i++ ) { if( psz_text[i] == '|' ) psz_text[i] = '\n'; } p_subtitle->psz_text = psz_text; return VLC_SUCCESS;}/* ParseSami */static char *ParseSamiSearch( text_t *txt, char *psz_start, const char *psz_str ){ if( psz_start && strcasestr( psz_start, psz_str ) ) { char *s = strcasestr( psz_start, psz_str ); return &s[strlen( psz_str )]; } for( ;; ) { char *p = TextGetLine( txt ); if( !p ) return NULL; if( strcasestr( p, psz_str ) ) { char *s = strcasestr( p, psz_str ); return &s[strlen( psz_str )]; } }}static int ParseSami( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ){ VLC_UNUSED( i_idx ); demux_sys_t *p_sys = p_demux->p_sys; text_t *txt = &p_sys->txt; char *s; int64_t i_start; unsigned int i_text; char text[8192]; /* Arbitrary but should be long enough */ /* search "Start=" */ if( !( s = ParseSamiSearch( txt, NULL, "Start=" ) ) ) return VLC_EGENERIC; /* get start value */ i_start = strtol( s, &s, 0 ); /* search <P */ if( !( s = ParseSamiSearch( txt, s, "<P" ) ) ) return VLC_EGENERIC; /* search > */ if( !( s = ParseSamiSearch( txt, s, ">" ) ) ) return VLC_EGENERIC; i_text = 0; text[0] = '\0'; /* now get all txt until a "Start=" line */ for( ;; ) { char c = '\0'; /* Search non empty line */ while( s && *s == '\0' ) s = TextGetLine( txt ); if( !s ) break; if( *s == '<' ) { if( !strncasecmp( s, "<br", 3 ) ) { c = '\n'; } else if( strcasestr( s, "Start=" ) ) { TextPreviousLine( txt ); break; } s = ParseSamiSearch( txt, s, ">" ); } else if( !strncmp( s, " ", 6 ) ) { c = ' '; s += 6; } else if( *s == '\t' ) { c = ' '; s++; } else { c = *s; s++; } if( c != '\0' && i_text+1 < sizeof(text) ) { text[i_text++] = c; text[i_text] = '\0'; } } p_subtitle->i_start = i_start * 1000; p_subtitle->i_stop = 0; p_subtitle->psz_text = strdup( text ); return VLC_SUCCESS;}/* ParseDVDSubtitle * Format * {T h1:m1:s1:c1 * Line1 * Line2 * ... * } * TODO it can have a header * { HEAD * ... * CODEPAGE=... * FORMAT=... * LANG=English * } * LANG support would be cool * CODEPAGE is probably mandatory FIXME */static int ParseDVDSubtitle( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ){ VLC_UNUSED( i_idx ); demux_sys_t *p_sys = p_demux->p_sys; text_t *txt = &p_sys->txt; char *psz_text; for( ;; ) { const char *s = TextGetLine( txt ); int h1, m1, s1, c1; if( !s ) return VLC_EGENERIC; if( sscanf( s, "{T %d:%d:%d:%d", &h1, &m1, &s1, &c1 ) == 4 ) { p_subtitle->i_start = ( (int64_t)h1 * 3600*1000 + (int64_t)m1 * 60*1000 + (int64_t)s1 * 1000 + (int64_t)c1 * 10) * 1000; p_subtitle->i_stop = 0; break; } } /* Now read text until a line containing "}" */ psz_text = strdup(""); if( !psz_text ) return VLC_ENOMEM; for( ;; ) { const char *s = TextGetLine( txt ); int i_len; int i_old; if( !s ) { free( psz_text ); return VLC_EGENERIC; } i_len = strlen( s ); if( i_len == 1 && s[0] == '}') { p_subtitle->psz_text = psz_text; return VLC_SUCCESS; } i_old = strlen( psz_text ); psz_text = realloc( psz_text, i_old + i_len + 1 + 1 ); if( !psz_text ) return VLC_ENOMEM; strcat( psz_text, s ); strcat( psz_text, "\n" ); }}/* ParseMPL2 * Format * [n1][n2]Line1|Line2|Line3... * where n1 and n2 are the video frame number (n2 can be empty) */static int ParseMPL2( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ){ VLC_UNUSED( i_idx ); demux_sys_t *p_sys = p_demux->p_sys; text_t *txt = &p_sys->txt; char *psz_text; int i; for( ;; ) { const char *s = TextGetLine( txt ); int i_start; int i_stop; if( !s ) return VLC_EGENERIC; psz_text = malloc( strlen(s) + 1 ); if( !psz_text ) return VLC_ENOMEM; i_start = 0; i_stop = 0; if( sscanf( s, "[%d][] %[^\r\n]", &i_start, psz_text ) == 2 || sscanf( s, "[%d][%d] %[^\r\n]", &i_start, &i_stop, psz_text ) == 3) { p_subtitle->i_start = (int64_t)i_start * 100000; p_subtitle->i_stop = (int64_t)i_stop * 100000; break; } free( psz_text ); } for( i = 0; psz_text[i] != '\0'; ) { /* replace | by \n */ if( psz_text[i] == '|' ) psz_text[i] = '\n'; /* Remove italic */ if( psz_text[i] == '/' && ( i == 0 || psz_text[i-1] == '\n' ) ) memmove( &psz_text[i], &psz_text[i+1], strlen(&psz_text[i+1])+1 ); else i++; } p_subtitle->psz_text = psz_text; return VLC_SUCCESS;}static int ParseAQT( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ){ VLC_UNUSED( i_idx ); demux_sys_t *p_sys = p_demux->p_sys; text_t *txt = &p_sys->txt; char *psz_text = strdup( "" ); int i_old = 0; int i_firstline = 1; for( ;; ) { int t; /* Time */ const char *s = TextGetLine( txt ); if( !s ) return VLC_EGENERIC; /* Data Lines */ if( sscanf (s, "-->> %d", &t) == 1) { p_subtitle->i_start = (int64_t)t; /* * FPS*/ p_subtitle->i_stop = 0; /* Starting of a subtitle */ if( i_firstline ) { i_firstline = 0; } /* We have been too far: end of the subtitle, begin of next */ else { TextPreviousLine( txt ); break; } } /* Text Lines */ else { i_old = strlen( psz_text ) + 1; psz_text = realloc( psz_text, i_old + strlen( s ) + 1 ); if( !psz_text ) return VLC_ENOMEM; strcat( psz_text, s ); strcat( psz_text, "\n" ); if( txt->i_line == txt->i_line_count ) break; } } p_subtitle->psz_text = psz_text; return VLC_SUCCESS;}static int ParsePJS( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ){ VLC_UNUSED( i_idx ); demux_sys_t *p_sys = p_demux->p_sys; text_t *txt = &p_sys->txt; char *psz_text; int i; for( ;; ) { const char *s = TextGetLine( txt ); int t1, t2; if( !s ) return VLC_EGENERIC; psz_text = malloc( strlen(s) + 1 ); if( !psz_text ) return VLC_ENOMEM; /* Data Lines */ if( sscanf (s, "%d,%d,\"%[^\n\r]", &t1, &t2, psz_text ) == 3 ) { /* 1/10th of second ? Frame based ? FIXME */ p_subtitle->i_start = 10 * t1; p_subtitle->i_stop = 10 * t2; /* Remove latest " */ psz_text[ strlen(psz_text) - 1 ] = '\0'; break; } free( psz_text ); } /* replace | by \n */ for( i = 0; psz_text[i] != '\0'; i++ ) { if( psz_text[i] == '|' ) psz_text[i] = '\n'; } p_subtitle->psz_text = psz_text; msg_Dbg( p_demux, "%s", psz_text ); return VLC_SUCCESS;}static int ParseMPSub( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ){ VLC_UNUSED( i_idx ); demux_sys_t *p_sys = p_demux->p_sys; text_t *txt = &p_sys->txt; char *psz_text = strdup( "" ); if( !p_sys->mpsub.b_inited ) { p_sys->mpsub.f_total = 0.0; p_sys->mpsub.f_factor = 0.0; p_sys->mpsub.b_inited = true; } for( ;; ) { float f1, f2; char p_dummy; char *psz_temp; const char *s = TextGetLine( txt ); if( !s ) return VLC_EGENERIC; if( strstr( s, "FORMAT" ) ) { if( sscanf (s, "FORMAT=TIM%c", &p_dummy ) == 1 && p_dummy == 'E') { p_sys->mpsub.f_factor = 100.0; break; } psz_temp = malloc( strlen(s) ); if( !psz_temp ) return VLC_ENOMEM; if( sscanf( s, "FORMAT=%[^\r\n]", psz_temp ) ) { float f_fps; f_fps = us_strtod( psz_temp, NULL ); if( f_fps > 0.0 && var_GetFloat( p_demux, "sub-fps" ) <= 0.0 ) var_SetFloat( p_demux, "sub-fps", f_fps ); p_sys->mpsub.f_factor = 1.0; free( psz_temp ); break; } free( psz_temp ); } /* Data Lines */ f1 = us_strtod( s, &psz_temp ); if( *psz_temp ) { f2 = us_strtod( psz_temp, NULL ); p_sys->mpsub.f_total += f1 * p_sys->mpsub.f_factor; p_subtitle->i_start = (int64_t)(10000.0 * p_sys->mpsub.f_total); p_sys->mpsub.f_total += f2 * p_sys->mpsub.f_factor; p_subtitle->i_stop = (int64_t)(10000.0 * p_sys->mpsub.f_total); break; } } for( ;; ) { const char *s = TextGetLine( txt ); if( !s ) return VLC_EGENERIC; int i_len = strlen( s ); if( i_len == 0 ) break; int i_old = strlen( psz_text ); psz_text = realloc( psz_text, i_old + i_len + 1 + 1 ); if( !psz_text ) return VLC_ENOMEM;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -