자막 다운로드 기능(+API) 추가

This commit is contained in:
joyfuI
2021-04-27 21:54:48 +09:00
parent 0cf53d3093
commit d04a71a348
5 changed files with 187 additions and 2 deletions

View File

@@ -106,6 +106,31 @@ API를 제공합니다. 다른 플러그인에서 동영상 정보나 다운로
`errorCode` | 에러 코드 | Integer
`index` | 동영상 인덱스. 이후 다운로드를 제어할 때 이 값이 필요함 | Integer
### /youtube-dl/api/sub
자막 다운로드 준비를 요청하는 API
#### Request
키 | 설명 | 필수 | 타입
--- | --- | --- | ---
`plugin` | 플러그인 이름 | O | String
`key` | 임의의 키. 이후 다운로드를 제어할 때 이 키가 필요함 | O | String
`url` | 동영상 주소 | O | String
`filename` | 파일명. 템플릿 규칙은 https://github.com/ytdl-org/youtube-dl/#output-template 참고. 미지정 시 사용자 설정 | X | String
`save_path` | 저장 폴더 경로. 미지정 시 사용자 설정 | X | String
`all_subs` | 모든 자막 다운로드 여부. 기본값: `false` | X | Boolean
`sub_lang` | 자막 언어. 두 자리 국가 코드. 콤마(,)를 구분자로 여러 개 지정 가능. `all_subs` 키가 `false`일 때만 유효. 기본값: `"ko"` | X | String
`auto_sub` | 자동생성 자막 다운로드 여부. 유튜브 전용. 기본값: `false` | X | Boolean
`dateafter` | 지정한 날짜 이후에 업로드된 동영상만 다운로드. 미지정 시 모든 동영상 다운로드 | X | String
`archive` | 다운로드한 동영상의 ID를 기록할 파일 경로. 파일이 이미 있으면 이미 다운로드한 동영상은 다운로드 하지 않음. 미지정 시 기록하지 않음 | X | String
`start` | 다운로드 준비 후 바로 다운로드를 시작할지 여부. 기본값: `false` | X | Boolean
`cookiefile` | 다운로드 시 필요한 쿠키 파일 경로 | X | String
`dateafter` 키에 넣을 수 있는 날짜는 `YYYYMMDD` 또는 `(now|today)[+-][0-9](day|week|month|year)(s)?` 형식의 문자열입니다.
#### Response
키 | 설명 | 타입
--- | --- | ---
`errorCode` | 에러 코드 | Integer
`index` | 동영상 인덱스. 이후 다운로드를 제어할 때 이 값이 필요함 | Integer
### /youtube-dl/api/start
다운로드 시작을 요청하는 API
#### Request
@@ -147,7 +172,7 @@ API를 제공합니다. 다른 플러그인에서 동영상 정보나 다운로
--- | --- | ---
`errorCode` | 에러 코드 | Integer
`status` | 요청을 받았을 당시의 상태 | Status
`type` | 다운로드 타입. `"video" "thumbnail"` | String
`type` | 다운로드 타입. `"video" "thumbnail" "subtitle"` | String
`start_time` | 다운로드 시작 시간 | String
`end_time` | 다운로드 종료 시간 | String
`temp_path` | 임시 폴더 경로 | String
@@ -160,6 +185,8 @@ API를 제공합니다. 다른 플러그인에서 동영상 정보나 다운로
v2.4.0
* 썸네일 다운로드 기능 추가
* thumbnail API 추가
* 자막 다운로드 기능 추가
* sub API 추가
* 설정에 경로 선택 버튼 추가
v2.3.1

View File

@@ -162,6 +162,46 @@ class LogicNormal(object):
logger.error(traceback.format_exc())
return None
@staticmethod
def sub(**kwagrs):
try:
logger.debug(kwagrs)
plugin = kwagrs['plugin']
url = kwagrs['url']
filename = kwagrs['filename']
temp_path = kwagrs['temp_path']
save_path = kwagrs['save_path']
opts = {
'skip_download': True
}
sub_lang = map(lambda x: x.strip(), kwagrs['sub_lang'].split(',')) # 문자열을 리스트로 변환
if 'all_subs' in kwagrs and str(kwagrs['all_subs']).lower() != 'false':
opts['allsubtitles'] = True
else:
opts['subtitleslangs'] = sub_lang
if 'auto_sub' in kwagrs and str(kwagrs['auto_sub']).lower() != 'false':
opts['writeautomaticsub'] = True
else:
opts['writesubtitles'] = True
if 'archive' in kwagrs and kwagrs['archive']:
opts['download_archive'] = kwagrs['archive']
if 'proxy' in kwagrs and kwagrs['proxy']:
opts['proxy'] = kwagrs['proxy']
if 'ffmpeg_path' in kwagrs and kwagrs['ffmpeg_path']:
opts['ffmpeg_location'] = kwagrs['ffmpeg_path']
if 'cookiefile' in kwagrs and kwagrs['cookiefile']:
opts['cookiefile'] = kwagrs['cookiefile']
dateafter = kwagrs.get('dateafter')
youtube_dl = MyYoutubeDL(plugin, 'subtitle', url, filename, temp_path, save_path, opts, dateafter)
youtube_dl.key = kwagrs.get('key')
LogicNormal.youtube_dl_list.append(youtube_dl) # 리스트 추가
return youtube_dl
except Exception as e:
logger.error('Exception:%s', e)
logger.error(traceback.format_exc())
return None
@staticmethod
def get_data(youtube_dl):
try:

View File

@@ -41,7 +41,8 @@ if ModelSetting.get_bool('activate_cors'):
menu = {
'main': [package_name, 'youtube-dl'],
'sub': [
['setting', '설정'], ['download', '다운로드'], ['thumbnail', '썸네일 다운로드'], ['list', '목록'], ['log', '로그']
['setting', '설정'], ['download', '다운로드'], ['thumbnail', '썸네일 다운로드'], ['sub', '자막 다운로드'], ['list', '목록'],
['log', '로그']
],
'category': 'vod'
}
@@ -103,6 +104,11 @@ def first_menu(sub):
arg['filename'] = default_filename if default_filename else LogicNormal.get_default_filename()
return render_template('%s_%s.html' % (package_name, sub), arg=arg)
elif sub == 'sub':
default_filename = ModelSetting.get('default_filename')
arg['filename'] = default_filename if default_filename else LogicNormal.get_default_filename()
return render_template('%s_%s.html' % (package_name, sub), arg=arg)
elif sub == 'list':
return render_template('%s_%s.html' % (package_name, sub), arg=arg)
@@ -175,6 +181,21 @@ def ajax(sub):
socketio_emit('add', youtube_dl)
return jsonify([])
elif sub == 'sub':
youtube_dl = LogicNormal.sub(plugin=package_name,
url=request.form['url'],
filename=request.form['filename'],
temp_path=ModelSetting.get('temp_path'),
save_path=ModelSetting.get('save_path'),
all_subs=request.form['all_subs'],
sub_lang=request.form['sub_lang'],
auto_sub=request.form['auto_sub'],
proxy=ModelSetting.get('proxy'),
ffmpeg_path=ModelSetting.get('ffmpeg_path'))
youtube_dl.start()
socketio_emit('add', youtube_dl)
return jsonify([])
elif sub == 'list':
ret = []
for i in LogicNormal.youtube_dl_list:
@@ -316,6 +337,51 @@ def api(sub):
socketio_emit('add', youtube_dl)
return jsonify(ret)
# 자막 다운로드 준비를 요청하는 API
elif sub == 'sub':
key = request.values.get('key')
url = request.values.get('url')
filename = request.values.get('filename', ModelSetting.get('default_filename'))
save_path = request.values.get('save_path', ModelSetting.get('save_path'))
all_subs = request.values.get('all_subs', False)
sub_lang = request.values.get('sub_lang', 'ko')
auto_sub = request.values.get('all_subs', False)
dateafter = request.values.get('dateafter', None)
archive = request.values.get('archive', None)
start = request.values.get('start', False)
cookiefile = request.values.get('cookiefile', None)
ret = {
'errorCode': 0,
'index': None
}
if None in (key, url):
return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음
if not url.startswith('http'):
return LogicNormal.abort(ret, 2) # 잘못된 동영상 주소
if not filename:
filename = LogicNormal.get_default_filename()
youtube_dl = LogicNormal.sub(plugin=plugin,
url=url,
filename=filename,
temp_path=ModelSetting.get('temp_path'),
save_path=save_path,
all_subs=all_subs,
sub_lang=sub_lang,
auto_sub=auto_sub,
dateafter=dateafter,
archive=archive,
proxy=ModelSetting.get('proxy'),
ffmpeg_path=ModelSetting.get('ffmpeg_path'),
key=key,
cookiefile=cookiefile)
if youtube_dl is None:
return LogicNormal.abort(ret, 10) # 실패
ret['index'] = youtube_dl.index
if start:
youtube_dl.start()
socketio_emit('add', youtube_dl)
return jsonify(ret)
# 다운로드 시작을 요청하는 API
elif sub == 'start':
index = request.values.get('index')

31
static/youtube-dl_sub.js Normal file
View File

@@ -0,0 +1,31 @@
"use strict";
const url = document.getElementById('url');
const download_btn = document.getElementById('download_btn');
// 모든 자막 다운로드
$('#all_subs').change(() => {
use_collapse('all_subs', true);
});
// 다운로드
download_btn.addEventListener('click', (event) => {
event.preventDefault();
if (!url.value.startsWith('http')) {
notify('URL을 입력하세요.', 'warning');
return;
}
fetch(`/${package_name}/ajax/sub`, {
method: 'POST',
cache: 'no-cache',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: get_formdata('#download')
}).then(response => response.json()).then(() => {
notify('분석중..', 'info');
}).catch(() => {
notify('다운로드 요청 실패', 'danger');
});
});

View File

@@ -0,0 +1,21 @@
{% extends "base.html" %}
{% block content %}
<form id="download">
{{ macros.setting_input_text('url', 'URL', placeholder='http:// 주소', desc='유튜브, 네이버TV 등 동영상 주소') }}
{{ macros.setting_input_text('filename', '파일명', value=arg['filename'], desc='템플릿 규칙은 https://github.com/ytdl-org/youtube-dl/#output-template 참고') }}
{{ macros.setting_checkbox('all_subs', '모든 자막 다운로드', value='False') }}
<div id="all_subs_div" class="collapse show">
{{ macros.setting_input_text('sub_lang', '자막 언어', value='ko', desc=['두 자리 국가 코드', '콤마(,)를 구분자로 여러 개 지정 가능']) }}
</div>
{{ macros.setting_checkbox('auto_sub', '자동생성 자막 다운로드', value='False', desc='유튜브 전용') }}
{{ macros.setting_button([['download_btn', '다운로드']]) }}
</form>
<script>
"use strict";
const package_name = '{{ arg["package_name"] }}';
</script>
<script src="{{ url_for('.static', filename='%s.js' % arg['template_name']) }}"></script>
{% endblock %}