encoding.py 5.42 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
20
21
22
23
@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')
		videoid = request.values.get('videoid')
		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
38
39
40
41
		data = {'path': video['path'], 'srcpath': video['srcpath'], 'srchash': video['srchash']}
		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
42
		schedule_job('remux', data)
43
	return ret
Julian Rother's avatar
Julian Rother committed
44

Julian Rother's avatar
Julian Rother committed
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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:
65
		old_source = query('SELECT * FROM sources WHERE id = ?', video['source'])[0]
Julian Rother's avatar
Julian Rother committed
66
67
68
69
70
71
72
73
		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']
74
	schedule_job('transcode', data, queue="background")
Julian Rother's avatar
Julian Rother committed
75

76
77
78
79
80
81
82
83
84
85
86
87
88
@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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
@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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
@edit_handler('chapters')
def chapter_changed(table, column, value, id):
	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')
def course_changed(table, column, value, id):
	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')
def lecture_changed(table, column, value, id):
	if column in ['title', 'comment', 'time', 'speaker']:
		schedule_remux(id)