private function uploadMedia($fileName, $bucket, $key)
    {
        // init multi-part upload
        $initUploadResponse = $this->bosClient->initiateMultipartUpload($bucket, $key);
        $uploadId = $initUploadResponse->uploadId;

        // do upload part
        try {
            $offset = 0;
            $partNumber = 1;
            $partSize = BosClient::MIN_PART_SIZE;
            $length = $partSize;
            $partList = array();
            $bytesLeft = filesize($fileName);

            while ($bytesLeft > 0) {
                $length = ($length > $bytesLeft) ? $bytesLeft : $length;
                $uploadResponse = $this->bosClient->uploadPartFromFile(
                    $bucket,
                    $key,
                    $uploadId,
                    $partNumber,
                    $fileName,
                    $offset,
                    $length);
                array_push($partList, array(
                    'partNumber' => $partNumber,
                    'eTag' => $uploadResponse->metadata['etag'],
                ));
                $offset += $length;
                $partNumber++;
                $bytesLeft -= $length;
            }

            // complete upload
            $this->bosClient->completeMultipartUpload($bucket, $key, $uploadId, $partList);
        } catch (\Exception $e) {
            $this->bosClient->abortMultipartUpload($bucket, $key, $uploadId);
            throw $e;
        }
    }