1. PHP / Говнокод #21991

    −22

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    96. 96
    97. 97
    98. 98
    99. 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;
    	}
    }

    Еще один "огрызок" из прошлого. Перекодировщик видео с ютуба, работал в несколько потоков и вполне стабильно держал небольшую нагрузку.

    Запостил: dacave, 18 Января 2017

    Комментарии (1) RSS

    • Настало время проверить, насколько стабильно будет держать нагрузку твой анус.
      Ответить

    Добавить комментарий