$expireTimestamp, self::PRIVILEGE_PUBLISH_AUDIO_STREAM => $expireTimestamp, self::PRIVILEGE_PUBLISH_VIDEO_STREAM => 0, self::PRIVILEGE_PUBLISH_DATA_STREAM => $expireTimestamp, ]; // Pack message $message = self::packUint16(1); // version: 1 (AccessToken) $message .= self::packUint32($currentTimestamp); $message .= self::packUint32($nonce); $message .= self::packString($channelName); $message .= self::packUint32($uid); $message .= self::packPrivileges($privileges); // HMAC-SHA256 signature $signature = hash_hmac('sha256', $appId . $currentTimestamp . $nonce . $channelName . $uid . self::packPrivileges($privileges), $appCertificate, true); $content = self::packString($signature) . $message; return self::VERSION . $appId . base64_encode($content); } private static function packUint16(int $v): string { return pack('n', $v); } private static function packUint32(int $v): string { return pack('N', $v); } private static function packString(string $v): string { return pack('n', strlen($v)) . $v; } private static function packPrivileges(array $privileges): string { ksort($privileges); $packed = pack('n', count($privileges)); foreach ($privileges as $key => $value) { $packed .= pack('n', $key) . pack('N', $value); } return $packed; } }