403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/sender/lib/integration/voximplant/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/sender/lib/integration/voximplant/audio.php
<?php
/**
 * Bitrix Framework
 * @package bitrix
 * @subpackage sender
 * @copyright 2001-2017 Bitrix
 */

namespace Bitrix\Sender\Integration\VoxImplant;

use Bitrix\Main\Application;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Json;
use Bitrix\Sender\Preset\Templates\AudioCall;

/**
 * Class Audio
 * @package Bitrix\Sender\Integration\VoxImplant
 */
class Audio
{
	const AUDIO_TYPE_PRESET = 'preset';
	const AUDIO_TYPE_FILE = 'file';

	/** @var string $fileId File name. */
	private $fileId = '';

	/** @var string $presetName Preset name. */
	private $presetName = '';

	/** @var string $messageCode Message code. */
	private $messageCode = '';

	private $duration;
	/**
	 * Create instance.
	 *
	 * @return static
	 */
	public static function create()
	{
		return new static();
	}

	/**
	 * SpeechRate constructor.
	 */
	public function __construct()
	{
	}

	/**
	 * With value.
	 *
	 * @param string $value Value from user interface.
	 * @return $this
	 */
	public function withValue($value)
	{
		if ($value)
		{
			if (intval($value) > 0)
			{
				$this->withFile($value);
			}
			else
			{
				$this->withPreset($value);
			}
		}
		return $this;
	}

	/**
	 * With json value.
	 *
	 * @param string $json Value as json string from DB.
	 * @return $this
	 */
	public function withJsonString($json)
	{
		if($json <> '')
		{
			try
			{
				$params = Json::decode($json);
				if($params['type'] == self::AUDIO_TYPE_PRESET)
				{
					$this->withPreset($params['preset']);
				}
				if($params['type'] == self::AUDIO_TYPE_FILE)
				{
					$this->withFile($params['fileId']);
				}
				if($params['duration'])
				{
					$this->duration = $params['duration'];
				}
			}
			catch(ArgumentException $e)
			{
			}
		}
		return $this;
	}

	/**
	 * With message code.
	 *
	 * @param string $messageCode Message code.
	 * @return $this
	 */
	public function withMessageCode($messageCode = null)
	{

		$this->messageCode = $messageCode;
		return $this;
	}

	/**
	 * With file.
	 *
	 * @param string $fileId File id.
	 * @return $this
	 */
	public function withFile($fileId = null)
	{

		$this->fileId = $fileId;
		return $this;
	}

	/**
	 * With preset.
	 *
	 * @param string $presetName Preset code.
	 * @return $this
	 */
	public function withPreset($presetName = null)
	{
		$this->presetName = $presetName;
		return $this;
	}

	/**
	 * Does audio created from a preset
	 *
	 * @return bool
	 */
	public function createdFromPreset()
	{
		return !!$this->presetName;
	}

	/**
	 * Get audio file url
	 * @param bool $useAbsoluteUrl Force using absolute url.
	 * @return bool|string|null
	 * @throws \Bitrix\Main\ArgumentNullException
	 * @throws \Bitrix\Main\ArgumentOutOfRangeException
	 */
	public function getFileUrl($useAbsoluteUrl = false)
	{
		if ($this->createdFromPreset())
		{
			$url = AudioCall::getAudioFileUrlByCode($this->getPresetCode());
		}
		else
		{
			$url = \CFile::GetPath($this->getFileId());
			if ($url && $useAbsoluteUrl && !$this->isRemoteFile($url))
			{
				$urlManager = \Bitrix\Main\Engine\UrlManager::getInstance();
				$url = $urlManager->getHostUrl() . $url;
			}
		}

		return $url;
	}

	/**
	 * Get value for db (as json string)
	 * @return bool|string
	 * @throws ArgumentException
	 */
	public function getDbValue()
	{
		if (!$this->getFileId() && !$this->getPreset())
		{
			return false;
		}
		$result = [
			'type' => $this->createdFromPreset() ? self::AUDIO_TYPE_PRESET : self::AUDIO_TYPE_FILE,
			'duration' => $this->getDuration()
		];
		if ($this->createdFromPreset())
		{
			$result['preset'] = $this->getPreset();
		}
		else
		{
			$result['fileId'] = $this->getFileId();
		}
		return Json::encode($result);
	}

	/**
	 * Get default audio preset url for player.
	 * @return string
	 */
	public function getDefaultFileUrl()
	{
		$code = AudioCall::getDefaultCode();
		return AudioCall::getAudioFileUrlByCode($code);
	}

	/**
	 * Get file id
	 * @return string
	 */
	public function getFileId()
	{
		return $this->fileId;
	}

	/**
	 * Get preset code
	 * @return string
	 */
	public function getPreset()
	{
		return $this->presetName;
	}

	/**
	 * Get message code
	 * @return string
	 */
	public function getMessageCode()
	{
		return $this->messageCode;
	}

	/**
	 * get duration of current audio
	 * @return integer
	 */
	public function getDuration()
	{
		if (!$this->duration)
		{
			if ($this->createdFromPreset())
			{
				$this->duration = $this->getPresetFileDuration($this->getPresetCode());
			}
			else
			{
				$this->duration = $this->getMp3fileDuration($this->getFileId());
			}
		}
		return $this->duration;
	}

	/**
	 * Get preset audio duration
	 * @param string $presetCode Preset code.
	 * @return bool
	 */
	protected function getPresetFileDuration($presetCode)
	{
		return AudioCall::getDurationByCode($presetCode);
	}

	/**
	 * Get preset code without message code
	 * @return string
	 */
	private function getPresetCode()
	{
		return mb_strpos($this->getPreset(), $this->getMessageCode()) === 0?
			mb_substr($this->getPreset(), mb_strlen($this->getMessageCode()) + 1) : $this->getPreset();
	}

	/**
	 * Get mp3 file duration
	 * @param int $fileId File id.
	 * @return int
	 */
	protected function getMp3fileDuration($fileId)
	{
		if (!$fileId)
			return false;

		$fileName = \CFile::GetPath($fileId);

		if ($this->isRemoteFile($fileName))
		{
			$tmpFileName = \CFile::GetTempName('', 'tmpfile.mp3');
			$request = new HttpClient([
				"socketTimeout" => 5,
				"streamTimeout" => 5
			]);
			$request->download($fileName, $tmpFileName);
			$fileName = $tmpFileName;
		}
		else
		{
			$fileName = Application::getDocumentRoot() . $fileName;
		}

		$file = fopen($fileName, "rb");

		$duration = 0;
		$header = fread($file, 100);
		$offset = $this->getId3v2TagLength($header);
		fseek($file, $offset, SEEK_SET);
		while (!feof($file))
		{
			$frame = fread($file, 10);
			if (strlen($frame) < 10)
			{
				break;
			}
			else
			{
				if ("\xff" == $frame[0] && (ord($frame[1]) & 0xe0))  // if 1111 1111 111x xxxx bits (header sequence) was found
				{
					list($frameLength, $frameDuration) = $this->getFrameInfo(substr($frame, 0, 4));
					if (!$frameLength)
					{
						return $duration;
					}
					$offset = $frameLength - 10;
					$duration += $frameDuration;
				}
				else
				{
					$offset = ('TAG' == substr($frame, 0, 3)) ? 118 : -9;
				}
				fseek($file, $offset, SEEK_CUR);
			}
		}
		return round($duration);
	}

	/**
	 * Get length of Id3v2 tag
	 * @param string $header Header.
	 * @return int
	 */
	private function getId3v2TagLength($header)
	{
		if ("ID3" == substr($header, 0, 3))
		{
			$hasExtendedHeader = (ord($header[5]) & 0x10) ? 1 : 0;
			$lengthByte1 = ord($header[6]);
			$lengthByte2 = ord($header[7]);
			$lengthByte3 = ord($header[8]);
			$lengthByte4 = ord($header[9]);
			if (!($lengthByte1 & 0x80) && !($lengthByte2 & 0x80) && !($lengthByte3 & 0x80) && !($lengthByte4 & 0x80))
			{
				$tagHeaderLength = 10 + ($hasExtendedHeader ? 10 : 0);
				$tagContentLength =
					(($lengthByte1 & 0x7f) << 21) +
					(($lengthByte2 & 0x7f) << 14) +
					(($lengthByte3 & 0x7f) << 7) +
					($lengthByte4 & 0x7f);

				return $tagHeaderLength + $tagContentLength;
			}
		}
		return 0;
	}

	/**
	 * Get frame info
	 * @param string $frame Frame.
	 * @return array
	 */
	private function getFrameInfo($frame)
	{
		$versions = [0 => '2.5', 2 => '2', 3 => '1'];
		$layers = [1 => '3', 2 => '2', 3 => '1'];
		$bitrates = [
			1 => [
				1 => [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448],
				2 => [0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384],
				3 => [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320]
			],
			2 => [
				1 => [0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256],
				2 => [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160],
				3 => [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160],
			]
		];
		$sampleRates = [
			'1' => [44100, 48000, 32000],
			'2' => [22050, 24000, 16000],
			'2.5' => [11025, 12000, 8000]
		];
		$samples = [
			1 => [1 => 384, 2 => 1152, 3 => 1152],
			2 => [1 => 384, 2 => 1152, 3 => 576]
		];

		$layerData = ord($frame[1]);
		$rateData = ord($frame[2]);

		$version = $versions[($layerData & 0x18) >> 3];
		$bitrateVersion = ($version == '2.5' ? 2 : $version);

		$layer = $layers[($layerData & 0x06) >> 1];

		$bitrateIndex = ($rateData & 0xf0) >> 4;
		$bitrate = $bitrates[$bitrateVersion][$layer][$bitrateIndex] ?: 0;

		$sampleRateIndex = ($rateData & 0x0c) >> 2;//0xc => b1100
		$sampleRate = $sampleRates[$version][$sampleRateIndex] ?: 0;
		$padding = ($rateData & 0x02) >> 1;

		if ($sampleRate <> 0)
		{
			$duration = $samples[$bitrateVersion][$layer] / $sampleRate;
		}

		if ($layer == 1)
		{
			$frameLength = intval(((12 * $bitrate * 1000 / $sampleRate) + $padding) * 4);
		}
		else
		{
			$frameLength = intval(((144 * $bitrate * 1000) / $sampleRate) + $padding);
		}

		return [$frameLength, $duration ?? 0];
	}

	/**
	 * Is $fileName an url?
	 * @param string $fileName Filename or url.
	 * @return bool
	 */
	private function isRemoteFile($fileName)
	{
		return preg_match('/^(https?):\/\/.*/', $fileName) === 1;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit