| 
Предыдущая тема
::
Следующая тема 
 | 
	 
	
	
	
		| Автор | 
		Сообщение | 
	 
	
		 neko_kun
 
  
  Зарегистрирован: 13.12.2007 Сообщения: 145
 
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 12:00 pm   Заголовок сообщения: Представление субтитров средствами веб. | 
				       | 
			 
			
				
  | 
			 
			
				Ранее нигде не сталкивался с таким, но, рас идея пришла ко мне, значит о ней знает как минимум еще 1 человек в Мире.
 
 
Итак, идея: показывать внешние субтитры в виде HTML отдельно от видеоролика.
 
 
Подзадачи:
 
1) тайминг - в определенный момент времени показывать нужную строку субтитров;
 
2) использование самых популярных форматов - ass, ssa, srt:
 
2.а) для начала - srt,
 
2.б) использование ass и ssa с сохранением оформления.
 
 
Просьба поделиться опытом, ссылками и мнениями.
 
 
Пока что нужно определиться
 
с алгоритмом тайминга - как быстро находить нужную строку субтитров;
 
и парсинга ass и ssa - может быть, уже есть готовые скрипты, перегоняющие их в srt с элементами html.
 
 
tt - что за формат? На форумах jw-плеера много о нем пишут, но как в него конвертировать, все-же мне не понятно да и хотелось бы не конвертировать вовсе, а просто пропарсить и отобразить.
 
 
Пока что думаю на счет тайминга:
 
1) массив от 1 до количества реплик - с индексами как в первых строчках srt;
 
2) громадный массив с элементами с шагом 0.1 сек;
 
3) пробежаться по субтитрам и если на заданный индекс массива п.2 приходится реплика, то присваивать элементу индекс реплики, иначе, присваивать 0, по которому будет располагаться пустая строка
 
4) при воспроизведении мы получаем текущую позицию с некой точностью менее 1 сек. (в обработчике события воспроизведения плеера); делим на наш шаг индексирования п.2 и отображаем строку массива п.1, адресуемую элементом массива п.2.
 
 
Короче, материал второго курса. Наверное я опять колесо открываю, надо поскрести по гуглу серьезнее. Ну а если вы сами уже скреблии, поделитесь, плиз.
 
 
ПС. Софтсаб в веб-плеерах встречал только на ютубе, но он там уж слишком простой и закрытый.
 
 
Плагин субтитров для flowplayer:
 
http://static.flowplayer.org/plugins/flash/captions.html
  Последний раз редактировалось: Вс Май 02, 2010 19:31 pm | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 Shitsu Гость
 
 
 
 
 
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 14:43 pm    | 
				       | 
			 
			
				
  | 
			 
			
				| а видео чем воспроизводится? | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 neko_kun
 
  
  Зарегистрирован: 13.12.2007 Сообщения: 145
 
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 15:19 pm    | 
				       | 
			 
			
				
  | 
			 
			
				Сейчас - jw-плеером
 
 
Экспериментальная копия
 
 
[/hide]Конкретный пример, и даже рабочий.
 
Вот только при перемотке нужно долго ждать субтитров.
  Последний раз редактировалось: Ср Окт 28, 2015 23:25 pm | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 triedge Гость
 
 
 
 
 
  | 
		 | 
	 
	
		| К началу | 
		 | 
	 
	
		 neko_kun
 
  
  Зарегистрирован: 13.12.2007 Сообщения: 145
 
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 17:19 pm    | 
				       | 
			 
			
				
  | 
			 
			
				triedge, нет, вряд ли. Там спецплеер для работы с простыми субтитрами. У нас все немного не в ту степь и гораздо круче.
 
 
В конечном итоге, должно получиться что-то в роде: берете любой плеер, находите у него обработчик события прогресса, вставляете функцию, подключаете субтитры - и они отображаются с таким оформлением, как в настольеом плеере. | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 Shitsu Гость
 
 
 
 
 
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 20:15 pm    | 
				       | 
			 
			
				
  | 
			 
			
				ну на tv.nkk.pp.ru вроде почти готовый скрипт. вот функция вывода субтитров:
 
 	  | Код: | 	 		  function mp3ChgTime(obj){
 
      curPos = obj['position'];
 
      if( issub ){
 
        if( curPos >= subcontent[curSubPos][0][0] )
 
          jQuery('#subs').html( subcontent[curSubPos][1] );
 
        if( curPos >= subcontent[curSubPos][0][1] ){
 
          curSubPos++;
 
          jQuery('#subs').html('<br>');
 
        }
 
      }
 
    } | 	  
 
subcontent[curSubPos][0][0] - это время начала показа в секундах
 
subcontent[curSubPos][0][1] - время конца
 
как доходит до конца, добавляет индекс: curSubPos++;
 
 
при перемотке назад соответственно это работать не будет. Добавте функцию вроде этой на событие перемотки:
 
 	  | Код: | 	 		  function onSeek(obj){
 
      curPos = obj['position'];
 
      curSubPos = 0; //обнуляем
 
       while ( curPos <= subcontent[curSubPos+1][0][0] ){
 
          curSubPos++; //прибавляем, пока не найдем текущую позицию
 
        }
 
      }
 
    } | 	  
 
 
Разбор srt там тоже есть. С ass, конечно, посложнее. и вообще то, если из оформления нужен только цвет и шрифт, то можно обойтись и срт. Причем ничего делать не нужно - там все теги прописываются как в хтмл | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 neko_kun
 
  
  Зарегистрирован: 13.12.2007 Сообщения: 145
 
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 20:22 pm    | 
				       | 
			 
			
				
  | 
			 
			
				| Shitsu, очень долго инкрементирует до заданного времени. Нужно либо оптимизировать поиск заданного времени (построить дерево и по нему искать или вообще хоть как-то искать а не тупо инкрементить), либо же, что я и хочу, сделать адресацию реплик по текущему времени с заданной точностью. | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 Shitsu Гость
 
 
 
 
 
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 20:43 pm    | 
				       | 
			 
			
				
  | 
			 
			
				| да ладно, там всего 200 строчек. | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 ГоСт
  Переводы
 
  
  Зарегистрирован: 03.07.2009 Сообщения: 668 Откуда: Москва
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 21:18 pm    | 
				       | 
			 
			
				
  | 
			 
			
				| Массив не? | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 neko_kun
 
  
  Зарегистрирован: 13.12.2007 Сообщения: 145
 
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 21:45 pm    | 
				       | 
			 
			
				
  | 
			 
			
				Вот что удобнее: поиск или адресация?
 
При адресации с точностью до 0.01сек., количество строк не важно, а фильм, продолжительностью 45 минут требует массива размером 45*60*100=270000 элементов.
 
Поиск же потребует меньше объемов, но больше вычислений и думать над ним надо будет тоже долго...
 
 
Попробуем с поиском.
 
Нужен алгоритм быстрого поиска с оптимизацией выборки последовательных элементов. То есть:
 
 
subcontent[1] = 'первая реплика';
 
subcontent[2] = 'вторая реплика';
 
subcontent[3] = 'третья реплика';
 
 
subtiming[1][0] = <начало реплики 1>;
 
subtiming[1][1] = <окончание реплики 1>;
 
subtiming[2][0] = <начало реплики 2>;
 
subtiming[2][1] = <окончание реплики 2>;
 
subtiming[3][0] = <начало реплики 3>;
 
subtiming[3][1] = <окончание реплики 3>;
 
 
на вход поступает время, в миллисекундах, нужно быстро находить № отображаемой реплики и отображать ее, причем так, чтобы при выборке последующей производилось минимум вычислений.
 
 
можно представить иначе:
 
 
times[<начало реплики 1>] = 'первая реплика';
 
times[<начало реплики 2>] = 'вторая реплика';
 
times[<начало реплики 3>] = 'третья реплика';
 
times[<окончание реплики 1>] = times[<окончание реплики 2>] = times[<окончание реплики 3>] = '';
 
 
воо, пошла соображалка.... | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 Shitsu Гость
 
 
 
 
 
  | 
		
			
				 Добавлено: Ср Апр 28, 2010 22:14 pm    | 
				       | 
			 
			
				
  | 
			 
			
				| адресация как-то извращенно выглядит + опасность переполнения массива. придется делать проверку каждую 0,01 секунду + понадобятся вычисления с плавающей запятой. Процессор намного быстрее складывает целые числа. К тому же поиск нужен только при перемотке, а при нормальном воспроизведении скрипт читается последовательно. | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 furyx Гость
 
 
 
 
 
  | 
		
			
				 Добавлено: Чт Апр 29, 2010 0:11 am    | 
				       | 
			 
			
				
  | 
			 
			
				я бы рекомендовал для начала определиться с постановкой задачи перед тем как хвататься за реализацию.
 
если речь идет исключительно об SRT, тогда мы УЖЕ имеем в исходнике отсортированный массив без пересечения фраз. если же речь пойдет об ASS, мне не совсем понятно, куда пойдут всякие /pos и тому подобные вещи, уже не говоря об таких вещах как цвет, который может совершенно быть не в тему цвета на форуме, не говоря уж об схемах.
 
 
ЗЫ откуда взялась точность 0.01? при 25 фреймах в секунду мы имеем 0.04. | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 neko_kun
 
  
  Зарегистрирован: 13.12.2007 Сообщения: 145
 
  | 
		
			
				 Добавлено: Чт Апр 29, 2010 2:13 am    | 
				       | 
			 
			
				
  | 
			 
			
				Shitsu, все, хороним эту глупую идею; уже 3 раза браузер через диспетчер задач выключал.
 
 
furyx, а это походу дела решится =))
 
Исходное разрешение в скрипте есть, размер экрана плеера известен;
 
плавать и фейдить, не получится, хотя не исключено jQuery имеется;
 
для начала, достаточно применять размер и тип шрифта, позиции титра на экране и тень.
 
 
=) конечно я не смогу в JS описать все фишки ssa, но и 5% хватит. | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 neko_kun
 
  
  Зарегистрирован: 13.12.2007 Сообщения: 145
 
  | 
		
			
				 Добавлено: Чт Апр 29, 2010 19:50 pm    | 
				       | 
			 
			
				
  | 
			 
			
				Все, пашет. Добавил рекурсивную функцию поиска - и заработало.
 
1 глюк пока заметил - после воспроизведения последней реплики и перемокте, субтитры не показываются, видать обращение не туда =).
 
 
Итак, в дополнение к JS, воспользуемся jQuery и Аяксом. Перед загрузкой ролика, подгружаем субтитр и парсим его:
 
 
 	  | Код: | 	 		  subtiming = [];
 
subcontent = [];
 
$('#subs').html('');
 
if( issub = $(this).hasClass('sub') ){
 
  var plpl = $(this).attr('href');
 
  $.get('v/'+plpl.substring(1,$(this).attr('href').length-3)+'srt',function(data){
 
    var replics, replic, subtmparts, tmtmp;
 
    var sep = data.indexOf('\r\n') == -1 ? '\n' : '\r\n';
 
    var replics = data.split(sep+sep);
 
 
    for( i=0; i<replics.length; i++ ){                                  // для каждой реплики
 
      replic = replics[i].split(sep);
 
      if( replic.length > 2 ){
 
        subtiming[replic[0]] = [];
 
 
        subtmparts = replic[1].split(' --> ');                          // парсинг тайминга
 
        if( subtmparts.length == 2 )
 
          for( j=0; j<2; j++ )
 
            if( tmtmp = subtmparts[j].match(/(\d{2})\:(\d{2})\:(\d{2})\,(\d{2})/) )
 
              subtiming[replic[0]][j] = tmtmp[1]*360000 + tmtmp[2]*6000 + tmtmp[3]*100 + parseInt( tmtmp[4] );
 
 
        subcontent[replic[0]] = replic[2];
 
        for( j=3; j<replic.length; j++ )                                // с фиксом реплик из нескольких строк
 
          subcontent[replic[0]] += '<br>' + replic[j];
 
 
      }
 
    }                                                                   // для каждой реплики
 
 
    setPlayer(plpl.substring(1));
 
  })
 
}
 
else
 
  setPlayer($(this).attr('href').substring(1)); | 	  
 
 
Обработчик прогресса jw-плеера и рекурсивная ф-ия поиска:
 
 
 	  | Код: | 	 		  function mp3ChgTime(obj){
 
  curPos = obj['position'];
 
  if( issub ){
 
    if( tmp = setLastPosId( lastPosId + 1 ) ){
 
      lastPosId = tmp;
 
      jQuery('#subs').html( subcontent[lastPosId] );
 
    }
 
    else
 
      jQuery('#subs').html( '' );
 
  }
 
}
 
 
function setLastPosId( id ){
 
  var pos = parseInt( curPos * 100 )
 
  try{
 
    if( pos >= subtiming[id][0] && pos < subtiming[id][1] )
 
      return id;
 
    if( pos < subtiming[id][0] )
 
      if( pos >= subtiming[id-1][1] )
 
        return 0
 
      else
 
        return setLastPosId( --id );
 
    if( pos >= subtiming[id][1] )
 
      if( pos < subtiming[id+1][0] )
 
        return 0
 
      else
 
        return setLastPosId( ++id );
 
  }catch(e){};
 
} | 	  
 
 
setPlayer() - перезагрузка плеера и ролика
  Последний раз редактировалось: Чт Апр 29, 2010 21:44 pm | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 Shitsu Гость
 
 
 
 
 
  | 
		
			
				 Добавлено: Чт Апр 29, 2010 20:33 pm    | 
				       | 
			 
			
				
  | 
			 
			
				если делать рекурсию, тогда уж методом деления отрезка пополам. А так можно получить переполнение стека.
 
 
Сущность метода: передаем функции два аргумента id1, id2, если они совпадают - возвращаем его, если нет - находим среднее id=(id1+id2)/2, сравниваем время subtiming[id] c pos. Если меньше, то вызываем эту же функцию с аргументами id1,id, если нет, то id,id2. | 
			 
			
				 | 
			 
			
				 | 
			 
		  | 
	 
	
		| К началу | 
		 | 
	 
	
		 | 
	 
 
  
	
	    
	   | 
	
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах Вы не можете прикреплять файлы к сообщениям Вы можете скачивать файлы, прикрепленные к сообщениям
  | 
   
 
  
Powered by :  phpBB © | Время : 0.1394с | SQL-запросов : 11 | Gzip : Вкл.
  
		 |