프로그래밍/PHP/JSP2010.11.22 11:35
가끔 유튜브에 자막파일이 함께 올라오는걸 볼 수 있습니다.

유튜브의 정책상 동영상업로드 따로 자막업로드 따로 할 수 있거든요,

그런데 가끔 그 자막을 받고 싶은데 영상 다운로더는 많이 보여도 자막 다운로더는 잘 보이지 않고

또 웹상에서 구현할 수 있다는 점에서 만들어봤습니다.

Youtube API 공부하시는 분들은 참고하시면 도움이 될듯.


	//input ; vid
	//output ; smi
		include_once "common/parser_php4.php";                       // 클래스 파일 include
		$sxml = "http://gdata.youtube.com/feeds/api/videos/$vid?v=2";
		$xml = file_get_contents($sxml);
		$parser = new XMLParser($xml);
		$parser->Parse();
		
		$title = $parser->document->media_group[0]->media_title[0]->tagData;
		
		$smi = "
					
					 $title 
					
					
					";
		
		
		$txml = "http://video.google.com/timedtext?v=$vid&type=list";
		$xml = file_get_contents($txml);         // 파싱할 대상XML 가져오기
		$parser = new XMLParser($xml);             // 객체생성 parser라는 객체를 생성함
		$parser->Parse();                                  // Parse()메소를 호출하여 xml을 dom 방식으로 파싱함
	
		$name = $parser->document->track[0]->tagAttrs['name'];
		$ln = $parser->document->track[0]->tagAttrs['lang_code'];
		
		
		$fxml = "http://video.google.com/timedtext?hl=$ln&lang=$ln&name=$name&v=$vid";
		$xml = file_get_contents($fxml);
		$parser = new XMLParser($xml);
		$parser->Parse();
		$xmlcap = $parser->document->tagChildren;
		
		foreach ($xmlcap as $entry) {
			$start = $entry->tagAttrs['start'];
			$start *= 1000;
			$smi = $smi."

"; $smi = $smi.$entry->tagData; $end = $entry->tagAttrs['dur']; $end = $start + $end*1000; $smi = $smi."

 "; } $smi = $smi."

";

코드 자체는 PHP로 구현하였습니다. 구조만 알면 누구나 쉽게 다른 언어로 바꿀 수 있을겁니다.

parser_php4 는 제가 php4 를 쓰는데 마땅한 XML파서가 없어서 웹에서 아무거나 주워왔습니다.

php5에는 기본으로 xml파서가 있는걸로 아는데 (simplexmlparesr였던가요?) 혹 필요하신 분이 있을까 해서 업로드 하겠습니다.

parser_php4에 대해 따로 설명드리지 않아도 될 정도로 간단하니 넘어가겠습니다.

http://gdata.youtube.com/feeds/api/videos/$vid?v=2
먼저 해당 주소에 $vid 에 video id를 넣어주면 동영상 정보가 XML로 제공됩니다. vid는 다들 아시다시피 "https://www.youtube.com/watch?v=vWH9dEfr8dI" 에서 v=다음에 오는걸 말합니다.

여기서 제목을 추출합니다. 동영상과 자막은 따로 관리가 되고 업로더도 다르기 때문에 번거롭지만 동영상 제목을 얻어내기 위해서 이렇게 해야합니다.

parser_php4 에서는 namespace 별로 xml을 파싱해주지 않기 때문에 "$parser->document->media_group[0]->media_title[0]->tagData;" 같이 번거롭게 접근했습니다만, 이름을 보시면 대충 어디의 부분인지 아실겁니다.

다음,
http://video.google.com/timedtext?v=$vid&type=list
는 해당 동영상에 첨부된 자막들의 정보를 보여줍니다. 유튜브 정책상 한 동영상에 여러 언어로 된 자막을 올릴 수 있으므로 여기서 적절히 원하는 것을 필터링해갑시다.

track 안의 name 애트리뷰트와 lang_code 애트리뷰트는 각각 자막파일의 이름, 언어를 뜻합니다. 이제 원하는것을 얻어냈으니 다음으로 갑니다.
http://video.google.com/timedtext?hl=$ln&lang=$ln&name=$name&v=$vid
이번에는 위의 주소에 hl="언어"&lang="언어"&name="이름"&v="비디오ID" 를 넣어 다시 파싱합니다. 이제 사용자가 원하는 자막이 나왔습니다.

그런데 자막이 XML로 되어있네요? TIMEDTEXT 형식으로 구성되어 있어서 기존 플레이어에서는 다른방법을 사용해야합니다. 대중적인 SMI방식으로 바꿔보지요.

		foreach ($xmlcap as $entry) {
			$start = $entry->tagAttrs['start'];
			$start *= 1000;
			$smi = $smi."

"; $smi = $smi.$entry->tagData; $end = $entry->tagAttrs['dur']; $end = $start + $end*1000; $smi = $smi."

 "; }


TIMEDTEXT 는 초단위로 구성되어 있기 때문에 마이크로초단위인 SMI를 위해 1000을 곱해줍시다. dur은 자막이 나오는 시간이므로 dur만큼 지난 후에 "nbsp;"를 출력해 자막을 사라지게 합시다.

이제 끝입니다.

더 자세한 내용은 Youtube API 페이지로 가셔야 하겠지만 자막을 얻어내는 부분만큼은 유튜브에 없더군요.. 결국 구글링해서 얻어내긴 했지만 모쪼록 다들 좋은 결과를 얻어내길 바랍니다. :)

덧. 티스토리 에디터가 태그를 멋대로 바꾸네요. 쩝... 그래서 원본파일도 첨부합니다.

Posted by Yria

댓글을 달아 주세요

  1. 유튜브에 자막 따로 올릴 수 있다는 것도 이제야 알았을 뿐더러 ㄷㄷㄷ
    뭔가 대단하시네요

    2010.12.05 04:43 신고 [ ADDR : EDIT/ DEL : REPLY ]