mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-05-30 09:26:00 -04:00
Adds a curated, per-encoder parameter-template library to ZoneMinder:
- Monitor edit page: a new Template row above the EncoderParameters
textarea offers per-encoder templates (Balanced / Archival / Low
Power / Low CPU). Apply merges the template's params into the
textarea, preserving user-only keys. Advisory lint flags option
keys that aren't recognised for the selected encoder. Switching
encoders offers a same-name template on the new encoder via a
native confirm.
- Options page: a new Encoder Templates tab with full CRUD —
list / edit / copy / delete — backed by a new CakePHP REST API
at /api/encoder_templates.
- Storage: a new EncoderTemplates DB table seeded with 14 shipped
defaults across libx264 / libx265 / h264_nvenc / hevc_nvenc /
h264_vaapi / hevc_vaapi. The table is mutable; ZM upgrades do not
re-seed user-edited rows.
- valid_keys (the lint allow-list) stays in PHP code as ffmpeg
vocabulary, not user data.
- Default params explicitly include pix_fmt to avoid the yuvj420p
HEVC HW-decode rejection issue we hit earlier.
No C++ change. The textarea content is parsed by the existing
av_dict_parse_string call in src/zm_videostore.cpp.
version.txt -> 1.39.6.
Specs: docs/superpowers/specs/2026-05-0{1,2}-*.md
Plans: docs/superpowers/plans/2026-05-0{1,2}-*.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
117 lines
3.5 KiB
PHP
117 lines
3.5 KiB
PHP
<?php
|
|
App::uses('AppController', 'Controller');
|
|
|
|
class EncoderTemplatesController extends AppController {
|
|
|
|
public $components = array('Paginator', 'RequestHandler');
|
|
|
|
public function beforeFilter() {
|
|
parent::beforeFilter();
|
|
}
|
|
|
|
public function index() {
|
|
$this->EncoderTemplate->recursive = -1;
|
|
$conditions = array();
|
|
if (!empty($this->request->query['Encoder'])) {
|
|
$conditions['EncoderTemplate.Encoder'] = $this->request->query['Encoder'];
|
|
}
|
|
$templates = $this->EncoderTemplate->find('all', array(
|
|
'conditions' => $conditions,
|
|
'order' => array('EncoderTemplate.Encoder' => 'ASC', 'EncoderTemplate.Name' => 'ASC'),
|
|
));
|
|
$this->set(array(
|
|
'encoderTemplates' => $templates,
|
|
'_serialize' => array('encoderTemplates'),
|
|
));
|
|
}
|
|
|
|
public function view($id = null) {
|
|
$this->EncoderTemplate->recursive = -1;
|
|
if (!$this->EncoderTemplate->exists($id)) {
|
|
throw new NotFoundException(__('Invalid encoder template'));
|
|
}
|
|
$template = $this->EncoderTemplate->find('first', array(
|
|
'conditions' => array('EncoderTemplate.Id' => $id),
|
|
));
|
|
$this->set(array(
|
|
'encoderTemplate' => $template,
|
|
'_serialize' => array('encoderTemplate'),
|
|
));
|
|
}
|
|
|
|
public function add() {
|
|
if ($this->request->is('post')) {
|
|
global $user;
|
|
$canEdit = (!$user) || ($user->System() == 'Edit');
|
|
if (!$canEdit) {
|
|
throw new UnauthorizedException(__('Insufficient privileges'));
|
|
}
|
|
$this->EncoderTemplate->create();
|
|
if ($this->EncoderTemplate->save($this->request->data)) {
|
|
$this->set(array(
|
|
'message' => 'Saved',
|
|
'id' => $this->EncoderTemplate->id,
|
|
'_serialize' => array('message', 'id'),
|
|
));
|
|
} else {
|
|
$this->response->statusCode(422);
|
|
$this->set(array(
|
|
'message' => 'Error',
|
|
'errors' => $this->EncoderTemplate->validationErrors,
|
|
'_serialize' => array('message', 'errors'),
|
|
));
|
|
}
|
|
}
|
|
}
|
|
|
|
public function edit($id = null) {
|
|
global $user;
|
|
$canEdit = (!$user) || ($user->System() == 'Edit');
|
|
if (!$canEdit) {
|
|
throw new UnauthorizedException(__('Insufficient privileges'));
|
|
}
|
|
if (!$this->EncoderTemplate->exists($id)) {
|
|
throw new NotFoundException(__('Invalid encoder template'));
|
|
}
|
|
$this->EncoderTemplate->id = $id;
|
|
if ($this->EncoderTemplate->save($this->request->data)) {
|
|
$this->set(array(
|
|
'message' => 'Saved',
|
|
'_serialize' => array('message'),
|
|
));
|
|
} else {
|
|
$this->response->statusCode(422);
|
|
$this->set(array(
|
|
'message' => 'Error',
|
|
'errors' => $this->EncoderTemplate->validationErrors,
|
|
'_serialize' => array('message', 'errors'),
|
|
));
|
|
}
|
|
}
|
|
|
|
public function delete($id = null) {
|
|
global $user;
|
|
$canEdit = (!$user) || ($user->System() == 'Edit');
|
|
if (!$canEdit) {
|
|
throw new UnauthorizedException(__('Insufficient privileges'));
|
|
}
|
|
$this->EncoderTemplate->id = $id;
|
|
if (!$this->EncoderTemplate->exists()) {
|
|
throw new NotFoundException(__('Invalid encoder template'));
|
|
}
|
|
$this->request->allowMethod('post', 'delete');
|
|
if ($this->EncoderTemplate->delete()) {
|
|
$this->set(array(
|
|
'message' => 'Deleted',
|
|
'_serialize' => array('message'),
|
|
));
|
|
} else {
|
|
$this->response->statusCode(500);
|
|
$this->set(array(
|
|
'message' => 'Error',
|
|
'_serialize' => array('message'),
|
|
));
|
|
}
|
|
}
|
|
}
|