encoding.py 5.47 KB
Newer Older
1
from server import *
Julian Rother's avatar
Julian Rother committed
2
import os.path
3

Julian Rother's avatar
Julian Rother committed
4
def set_metadata(dest, course, lecture):
5
	chapters = query('SELECT text, time FROM chapters WHERE lecture_id = ? AND visible ORDER BY time', lecture['id'])
Julian Rother's avatar
Julian Rother committed
6
7
8
9
	metadata = {'title': lecture['title'], 'album': course['title'],
		'description': lecture['comment'],
		'date': lecture['time'].strftime('%m/%d/%Y'),
		'artist': lecture['speaker'] if lecture['speaker'] else course['organizer']}
Julian Rother's avatar
Julian Rother committed
10
11
12
	dest['metadata'] = metadata
	dest['chapters'] = chapters

13
14
15
16
17
18
19
@app.route('/internal/jobs/add/remux', methods=['GET', 'POST'])
@mod_required
@csrf_protect
def schedule_remux(lectureid=None, videoid=None):
	ret = None
	if not lectureid:
		lectureid = request.values.get('lectureid')
Julian Rother's avatar
Julian Rother committed
20
		videoid = int(request.values.get('videoid', 0))
21
22
23
		if not lectureid:
			lectureid = query('SELECT lecture_id FROM videos WHERE id = ?', videoid)[0]['lecture_id']
		ret = redirect(request.values.get('ref', url_for('jobs_overview')))
Julian Rother's avatar
Julian Rother committed
24
25
26
27
28
29
30
	lecture = query('SELECT * FROM lectures WHERE id = ?', lectureid)[0]
	course = query('SELECT * FROM courses WHERE id = ?', lecture['course_id'])[0]
	videos = query('''SELECT videos.*, sources.path AS srcpath, sources.hash AS srchash, formats.options AS fmtopts
			FROM videos
			JOIN sources ON videos.source = sources.id
			JOIN formats ON videos.video_format = formats.id
			WHERE videos.lecture_id = ?''', lectureid)
Julian Rother's avatar
Julian Rother committed
31
32
33
	for video in videos:
		if not video['source']:
			continue
34
35
		if videoid and video['id'] != videoid:
			continue
Julian Rother's avatar
Julian Rother committed
36
37
		data = {'path': video['path'], 'srcpath': video['srcpath'],
			'srchash': video['srchash'], 'video_id': video['id']}
Julian Rother's avatar
Julian Rother committed
38
39
40
41
42
		fmt = json.loads(video['fmtopts'])
		if 'format' in fmt:
			data['format'] = fmt['format']
		data['options'] = fmt.get('options', {})
		set_metadata(data, course, lecture)
Julian Rother's avatar
Julian Rother committed
43
		schedule_job('remux', data)
44
	return ret
Julian Rother's avatar
Julian Rother committed
45

Julian Rother's avatar
Julian Rother committed
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def schedule_transcode(source, fmt_id=None, video=None):
	if video:
		fmt_id = video['video_format']
		assert(video['lecture_id'] == source['lecture_id'])
	assert(fmt_id != None)
	fmt = query('SELECT * FROM formats WHERE id = ?', fmt_id)[0]
	lecture = query('SELECT * FROM lectures WHERE id = ?', source['lecture_id'])[0]
	course = query('SELECT * FROM courses WHERE id = ?', lecture['course_id'])[0]
	data = {'input': {'path': source['path'], 'streams': []}, 'output': json.loads(fmt['options']), 'filters': []}
	if source['type'] == 'plain':
		stream = {'name': 'video', 'type': 'video'}
		data['input']['streams'].append(stream)
		stream = {'name': 'audio', 'type': 'audio'}
		data['input']['streams'].append(stream)
	else:
		assert(False)
	set_metadata(data['output'], course, lecture)
	basename = os.path.basename(source['path']).rsplit('.', 1)[0]
	data['output']['path'] = 'pub/'+course['handle']+'/'+basename+fmt['suffix']
	if video:
66
		old_source = query('SELECT * FROM sources WHERE id = ?', video['source'])[0]
Julian Rother's avatar
Julian Rother committed
67
68
69
70
71
72
73
74
		data['output']['path'] = video['path']
		data['video_id'] = video['id']
		data['srcpath'] = old_source['path']
		data['srchash'] = old_source['hash']
	else:
		data['lecture_id'] = lecture['id']
	data['format_id'] = fmt['id']
	data['source_id'] = source['id']
75
	schedule_job('transcode', data, queue="background")
Julian Rother's avatar
Julian Rother committed
76

77
78
79
80
81
82
83
84
85
86
87
88
89
@app.route('/internal/jobs/add/reencode', methods=['GET', 'POST'])
@mod_required
@csrf_protect
@handle_errors('jobs_overview', 'Video nicht gefunden!', 404, IndexError)
def schedule_reencode():
	video = query('SELECT * FROM videos WHERE id = ?', request.values['videoid'])[0]
	if not video['source']:
		flash('Manuell erstellte Videos können nicht neukodiert werden!')
	else:
		source = query('''SELECT sources.* FROM sources WHERE sources.id = ? ORDER BY time_created''', video['source'])[-1]
		schedule_transcode(source, video=video)
	return redirect(request.values.get('ref', url_for('jobs_overview')))

Julian Rother's avatar
Julian Rother committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
@job_handler('probe-raw')
def update_lecture_videos(jobid, jobtype, data, state, status):
	if 'lecture_id' not in data:
		return
	if 'source_id' not in data:
		modify('INSERT INTO sources (lecture_id, path, type, hash, time_created) VALUES (?, ?, ?, ?, ?)',
				data['lecture_id'], data['path'], 'plain', status['hash'], datetime.now())
	sources = query('SELECT * FROM sources WHERE sources.lecture_id = ? ORDER BY time_created', data['lecture_id'])
	if not sources:
		return
	latest = sources[-1]
	videos = query('SELECT * FROM videos WHERE videos.lecture_id = ?', data['lecture_id'])
	current_fmts = [v['video_format'] for v in videos]
	formats = query('''SELECT formats.* FROM formats
			JOIN profiles ON formats.id = profiles.format
			JOIN courses ON profiles.name = courses.profile
			JOIN lectures ON courses.id = lectures.course_id
			WHERE lectures.id = ?''', data['lecture_id'])
	for fmt in formats:
		if fmt['id'] not in current_fmts:
			schedule_transcode(latest, fmt_id=fmt['id'])
	for video in videos:
		if video['source'] != latest['id']:
			schedule_transcode(latest, video=video)

Julian Rother's avatar
Julian Rother committed
115
@edit_handler('chapters')
116
def chapter_changed(table, column, value, id, user):
Julian Rother's avatar
Julian Rother committed
117
118
119
120
121
122
123
124
125
	print('chapter_changed')
	chapters = query('SELECT * FROM chapters WHERE id = ?', id)
	if not chapters:
		return
	chapter = chapters[0]
	if column in ['visible', 'deleted'] or (chapter['visible'] and not chapter['deleted']):
		schedule_remux(chapter['lecture_id'])

@edit_handler('courses')
126
def course_changed(table, column, value, id, user):
Julian Rother's avatar
Julian Rother committed
127
128
129
130
131
132
133
	if column not in ['title', 'organizer']:
		return
	lectures = query('SELECT * FROM lectures WHERE course_id = ?', id)
	for lecture in lectures:
		schedule_remux(lecture['id'])

@edit_handler('lectures')
134
def lecture_changed(table, column, value, id, user):
Julian Rother's avatar
Julian Rother committed
135
136
137
	if column in ['title', 'comment', 'time', 'speaker']:
		schedule_remux(id)