- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
class EncoderCommand extends CConsoleCommand {
public function actionStart()
{
if (file_exists($this->getLockFile())) { throw new RuntimeException('Encoder already started!'); return false; }
if (!touch($this->getLockFile())) { throw new RuntimeException('Can not create lock file '.$this->getLockFile()); return false; }
Yii::setPathOfAlias('webroot', dirname(dirname(dirname(__FILE__))));
if (file_exists($this->getLogFile()))
unlink($this->getLogFile());
foreach (EncodingQueue::model()->findAll('phase != :lastPhase', array(':lastPhase' => EncodingQueue::ENCODED)) as $task) {
// exec('php '.Yii::getPathOfAlias('application').'/yiic.php encoder process '.$task->id, $output);
// echo implode(PHP_EOL, $output);
$this->process($task);
}
unlink($this->getLockFile());
}
public function process(EncodingQueue $task) {
// ещё не скачано
if ($task->phase < EncodingQueue::DOWNLOADED) {
$task->phase = EncodingQueue::DOWNLOADING;
$task->save();
if (!empty($task->remote_source_file) && !file_exists(Yii::getPathOfAlias('webroot').$task->source_file)) {
echo 'Downloading to '.$task->source_file.' ...'.PHP_EOL;
file_put_contents($this->getLogFile(), null);
$cmd = 'curl -o '.escapeshellarg(Yii::getPathOfAlias('webroot').$task->source_file).' '.escapeshellarg($task->remote_source_file).' 1>'.$this->getLogFile().' 2>&1 &';
exec($cmd, $output);
echo implode(PHP_EOL, $output);
$i = 0;
while (true) {
$c = file_get_contents($this->getLogFile());
$f = explode("\r", $c);
if (count($f) > 0) {
$s = trim($f[count($f) - 1]);
if (substr($c, -1) == "\n")
break;
sscanf($s, '%3d', $progress);
$task->progress = $progress;
$task->save();
echo '...'.$progress.'%'.PHP_EOL;
}
sleep(1);
}
}
$task->progress = -1;
$task->phase = EncodingQueue::DOWNLOADED;
$task->save();
}
// ещё не перекодировано
if ($task->phase < EncodingQueue::ENCODED) {
$task->phase = EncodingQueue::ENCODING;
$task->save();
if (!empty($task->ffmpeg_options)) {
echo 'Encoding to '.$task->target_file.' ...'.PHP_EOL;
file_put_contents($this->getLogFile(), null);
$cmd = 'ffmpeg -y -i '.escapeshellarg(Yii::getPathOfAlias('webroot').$task->source_file).' '.$task->ffmpeg_options.' '.escapeshellarg(Yii::getPathOfAlias('webroot').$task->target_file).' 1>'.$this->getLogFile().' 2>&1 &';
exec($cmd, $output);
echo implode(PHP_EOL, $output);
$i = 0;
while (true) {
$c = file_get_contents($this->getLogFile());
if (!empty($c)) {
preg_match('~Duration: (.*?), start:~', $c, $matches);
$duration = $this->timeToSeconds($matches[1]);
preg_match_all('~time=(.*?) bitrate~', $c, $matches);
$last = array_pop($matches);
if (is_array($last)) $last = array_pop($last);
$curTime = $this->timeToSeconds($last);
$progress = 100*$curTime/$duration;
$task->progress = $progress;
$task->save();
echo '...'.$progress.'%'.PHP_EOL;
if (preg_match('~video:[0-9]+kB audio:[0-9]+kB~u', $c))
break;
}
sleep(1);
}
} else {
echo 'Copying '.Yii::getPathOfAlias('webroot').$task->source_file.' to '.Yii::getPathOfAlias('webroot').$task->target_file.' ...'.PHP_EOL;
copy(Yii::getPathOfAlias('webroot').$task->source_file, Yii::getPathOfAlias('webroot').$task->target_file);
}
$task->progress = -1;
$task->phase = EncodingQueue::ENCODED;
$task->save();
}
}
public function getLockFile($postfix = null) { return Yii::getPathOfAlias('application').'/runtime/encoder'.($postfix != null ? '.'.$postfix : null).'.lock'; }
public function getLogFile($postfix = null) { return Yii::getPathOfAlias('application').'/runtime/encoder'.($postfix != null ? '.'.$postfix : null).'.log'; }
/**
* Translates string like "00:04:12.17" into "252.17"
*/
protected function timeToSeconds($rawDuration) {
$ar = array_reverse(explode(':', $rawDuration));
$duration = floatval($ar[0]);
if (!empty($ar[1])) $duration += intval($ar[1]) * 60;
if (!empty($ar[2])) $duration += intval($ar[2]) * 60 * 60;
return $duration;
}
}
Еще один "огрызок" из прошлого. Перекодировщик видео с ютуба, работал в несколько потоков и вполне стабильно держал небольшую нагрузку.
huge_cock 18.01.2017 07:07 # +2