2015년 8월 15일 토요일

[KODI] tvheadend 녹화 영상 KODI 자동 등록


tvheadend로 녹화 해서 KODI로 영상을 감상 하고 싶을 때 장애물이 하나 있습니다. 라이브러리 등록이 좀 불편하다는 점이죠. EPG정보를 이용 해 녹화 할 때는 회차번호가 저장되지 않기 때문에 수동으로 회차번호를 넣어 주거나, 영상이 저장되는 폴더에 회차번호가 없는 파일들을 변환할 수 있는 스크립트를 만들어 써야 합니다. 일전에 공유한 스크립트를 응용하는 방법을 정리해서 다시 공유 해 봅니다.

tvheadend의 post-processor command를 이용해 녹화 된 영상의 썸네일을 만들고 KODI에 자동으로 등록 하는 것 까지 한번에 처리합니다.

먼저 php가 쉘에서 실행될 수 있는 환경을 만듭니다.

/etc/php/conf.d/usersettings.ini 파일을 열어서 스크립트가 저장되는 폴더를 추가합니다.

display_errors = On
open_basedir = /etc.defaults:/etc:/usr/syno/synoman:/var/services/tmp:/var/services/web:/var/services/homes:/volume3/video/
apc.enabled = 1
opcache.enable = 1
opcache.enable_cli = 1

두번째 줄에 해당 경로를 추가 하시면 됩니다. 이러면 쉘에서 php 스크립트를 실행할 수 있습니다.

아래 코드를 tvh_to_kodi.php로 저장합니다.

<?
// php aaa.php '프로그램제목' '시작시간' '파일이름' '전체경로' 형태로 실행
// argv[1] = 프로그램제목
// argv[2] = 시작시간
// argv[3] = 파일이름
// argv[4] = 전체경로

//프로그램 번호 알아냄
function prog_no_find($t){
 $name=$t;
 $name=str_replace(" ","+",$name);
 $address="http://movie.daum.net/search.do?type=tv&q=".$name;
 preg_match('/tvprogramid=\b(\d+?)\b/i',file_get_contents($address),$result); //$result[1]=programno
 return $result[1];
}

function convert_episode($t){
 // $t = 프로그램 번호 찾는 함수의 리턴 값으로 해당 프로그램의 문서를 불러온다.
 $address="http://m.movie.daum.net/m/tv/episode?tvProgramId=".$t;
 preg_match_all('/"episodeId" : "(\d+)?"/i',file_get_contents($address),$episodeId);
 preg_match_all('/"sequence" : (\d+)?/i',file_get_contents($address),$episodeSeq);
 preg_match_all('/"title" : "(.+)?"/i',file_get_contents($address),$episodeTitle);
 preg_match_all('/"introduceDescription" : "(.+?)"/i',file_get_contents($address),$episodeIntroduce);
 preg_match_all('/"broadcastDate" : "(\d+?)"/i',file_get_contents($address),$telecastDate);
 $result[episodeId]=$episodeId[1];
 $result[episodeSeq]=$episodeSeq[1];
 $result[episodeTitle]=$episodeTitle[1];
 $result[episodeIntroduce]=$episodeIntroduce[1];
 $result[telecastDate]=$telecastDate[1];
 //타이틀 정보가 없을 경우 날짜 정보로 대체 한다. 
 for ($i=0;$i<count($result[episodeId]);$i++){
  if($result[episodeId][$i] > 1 && $result[episodeTitle][$i]==""){
   $result[episodeTitle][$i]=preg_replace('/(\d{4})(\d{2})(\d{2})/i', '\2월 \3일', $result[telecastDate][$i]);
  }
 }
 return $result;
}

function find_episode_data($p,$s){
 $episodeSet=$p; 
 $broadcastDate=date(Ymd,$s); 
 //daum에 회차정보가 아예 없을 경우
 //회차번호 dummy 생성 : 15년을 1xxx, 16년은 2xxx, 15년 33주는 133x, 15년 33주 수요일은 1333
 if(count($episodeSet[episodeId])<1){
    $year=strftime("%y",$s);
    $week=strftime("%V%u",$s);
    $year=$year-14;
    $episodeData[episodeId]='1';
    $episodeData[episodeSeq]=$year.$week;
    $episodeData[episodeTitle]=preg_replace('/(\d{4})(\d{2})(\d{2})/i', '\2월 \3일', $broadcastDate);
    $episodeData[episodeIntroduce]="";
    $episodeData[telecastDate]=$broadcastDate;
 }
 //daum에 회차정보가 있을 경우
 else{
  for ($i=0;$i<count($episodeSet[episodeId]);$i++){
   if($episodeSet[telecastDate][$i]==$broadcastDate){
    $episodeData[episodeId]=$episodeSet[episodeId][$i];
    $episodeData[episodeSeq]=$episodeSet[episodeSeq][$i];
    $episodeData[episodeTitle]=$episodeSet[episodeTitle][$i];
    $episodeData[episodeIntroduce]=$episodeSet[episodeIntroduce][$i];
    $episodeData[telecastDate]=$episodeSet[telecastDate][$i];
   }
  }
 }
 return $episodeData;
}

function create_Thum($epiData,$f){  // $f is fullpath variables of tvheadend. argv[4]
 $ffmpeg = "/volume1/@appstore/AudioStation/bin/ffmpeg"; //사용할 ffmpeg 경로지정. 많이쓰는 ffmpeg with DTS는 썸네일 생성 불가. AudioStation용 가능
 $thumb_name=preg_replace('/(.+)(\.\d{4}-\d{2}-\d{2})(\.\w{3})/i', '\1.E'.$epiData[episodeSeq].'\2-thumb.png', $f);
 $command=$ffmpeg." -ss 00:10:15 -i '".$f."' -r 1 -y -an -vframes 1 '".$thumb_name."'";
 exec($command);
 return $thumb_name;
}
function fix_filename($epiData,$f){
 $fixname=preg_replace('/(.+)(\.\d{4}-\d{2}-\d{2}.\w{3})/i', '\1.E'.$epiData[episodeSeq].'\2', $f);
 rename($f,$fixname);
 return $fixname;
}


$t=prog_no_find($argv[1]); 
$ss=convert_episode($t); 
$epidata=find_episode_data($ss,$argv[2]); 
create_thum($epidata,$argv[4]);
fix_filename($epidata,$argv[4]);

//KODI에 라이브러리 업데이트 하라고 시킨다.
exec("curl --data-binary '{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.Scan\", \"id\": \"mybash\"}' -H 'content-type: application/json;' http://xbmc:xbmc@localhost:7070/jsonrpc");

?>

72번줄의 썸네일 만들기 위한 ffmpeg은 지난번과 같이 오디오스테이션 설치 시 같이 설치 되는 ffmpeg입니다. 시놀로지 이용 시 기본 설치 된 ffmpeg은 썸네일을 못 만드는 버전이니 참고하시기 바랍니다. 다른 OS 쓰시는 분들은 별도 경로 없이  ffmpeg -ss 00:10:15 -i.... 이렇게 변경합니다.

90번줄의 curl 실행 명령은 KODI의 http 웹 서버 옵션을 켜 두었을 때 사용 가능합니다.
뒷부분의 "http://xbmc:xbmc@localhost:7070/jsonrpc"는 본인의 kodi환경에 맞춰서 id, pw, ip, port 번호를 변경해서 사용합니다.


이번엔 tvheadend configuration -> Recording 에서 post-processor command에 아래 내용을 입력합니다.

php /스크립트경로/tvh_to_kodi.php "%t" "%S" "%b" "%f"

e.g) php /volume1/video/Scripts/tvh_to_kodi.php "%t" "%S" "%b" "%f"

대소문자 구분에 유의 합니다.

파일명에 방송날짜 정보가 기록 되도록 'Include data in filename"옵션을 꼭 켜 두셔야 합니다.

간단하게 동작방식을 설명하자면,
녹화 끝나면 녹화 완료 된 영상의 파일명에 다음티비쇼정보에서 회차번호를 찾아 넣어줍니다.
회차번호가 없다면 더미데이터를 만들어 넣어 줍니다. 썸네일 등장 속도를 빠르게 하기 위해 썸네일 파일을 만들어 주고 KODI에 라이브러리 업데이트를 요청합니다.




댓글 1개:

  1. 안녕하세요 ~
    매번 좋은 정보 감사합니다 (__)
    이번에도 열심히 따라 해보았지만.. 도통 아무런 반응을 하지 않고 있습니다 ;;;
    혹시 다른 무언가를 추가 해야하는건지요 ?

    답글삭제