> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tải lên Tệp Media Lớn

> Đối với việc tải lên tệp lớn hơn 10 MB, lấy một URL đã được ký sẵn để tải lên tệp

export const HeaderAPI = ({noProfileKey, profileKeyRequired}) => <>
    <ParamField header="Authorization" type="string" required>
      <a href="/apis/overview#authorization">API Key</a> of the Primary Profile.
      <br />
      <br />
      Format: <code>Authorization: Bearer API_KEY</code>
    </ParamField>
    {!noProfileKey && (profileKeyRequired ? <ParamField header="Profile-Key" type="string" required>
          <a href="/apis/overview#profile-key-format">Profile Key</a> of a User Profile.
          <br />
          <br />
          Format: <code>Profile-Key: PROFILE_KEY</code>
        </ParamField> : <ParamField header="Profile-Key" type="string">
          <a href="/apis/overview#profile-key-format">Profile Key</a> of a User Profile.
          <br />
          <br />
          Format: <code>Profile-Key: PROFILE_KEY</code>
        </ParamField>)}
  </>;

export const PlansAvailable = ({plans = [], maxPackRequired}) => {
  let displayPlans = plans;
  if (plans && plans.length === 1) {
    const lowerCasePlan = plans[0].toLowerCase();
    if (lowerCasePlan === "business") {
      displayPlans = ["Launch", "Business", "Enterprise"];
    } else if (lowerCasePlan === "premium") {
      displayPlans = ["Premium", "Launch", "Business", "Enterprise"];
    }
  }
  return <Note>
Available on {displayPlans.length === 1 ? "the " : ""}
{displayPlans.join(", ").replace(/\b\w/g, l => l.toUpperCase())}{" "}
{displayPlans.length > 1 ? "plans" : "plan"}.

{maxPackRequired && <span onClick={() => window.open('https://www.ayrshare.com/docs/additional/maxpack', '_self')} className="flex items-center mt-2 cursor-pointer">
 <span className="px-1.5 py-0.5 rounded text-sm" style={{
    backgroundColor: '#C264B6',
    color: 'white',
    fontSize: '12px'
  }}>
   Max Pack required
 </span>
</span>}
</Note>;
};

<PlansAvailable plans={["premium"]} maxPackRequired={false} />

Đối với việc tải lên tệp lớn hơn 10 MB, lấy một URL đã được ký sẵn (presigned URL) để tải lên tệp.

<ul class="custom-bullets">
  <li>Kích thước tải lên tệp tối đa 5 GB.</li>
  <li>URL tải lên đã được ký sẵn có hiệu lực trong 30 phút sau khi được tạo.</li>

  <li>
    URL truy cập khả dụng trong 30 ngày sau khi tải lên. Tất cả các bài đăng đã xuất bản đều không bị ảnh hưởng trên
    các mạng xã hội. Các bài đăng đã lên lịch vượt quá khung thời gian đó sẽ dẫn đến lỗi vào lúc
    xuất bản.
  </li>
</ul>

<Tip>Nếu bạn đã có media có thể truy cập bằng URL bên ngoài, chẳng hạn như một S3 bucket, bạn có thể bỏ qua việc tải các tệp lên Ayrshare. Chỉ cần POST đến endpoint `/post` với URL có thể truy cập từ bên ngoài của bạn trong tham số body `mediaURLs` và tệp của bạn sẽ tự động được tải lên.</Tip>

## Tham số Header

<HeaderAPI noProfileKey={true} />

## Tham số Query

<ParamField query="fileName" type="string">
  Nếu contentType không có mặt, thì tên tệp đầy đủ với phần mở rộng là bắt buộc.

  Tên của tệp sẽ được tải lên. Phải bao gồm phần mở rộng như .png, .jpg, .mov, .mp4, v.v.
</ParamField>

<ParamField query="contentType" type="string">
  Content-type của media đang được tải lên. Các định dạng hợp lệ bao gồm: `mp4`, `mov`, `png`, `jpg`, hoặc `jpeg`.

  Ví dụ, nếu tệp là một tệp Quicktime .mov, thì contentType phải là `mov`.

  Nếu không có mặt, application/octet-stream sẽ được sử dụng.
</ParamField>

<RequestExample>
  ```bash cURL theme={"system"}
  curl \
  -H "Authorization: Bearer [API Key]" \
  -X GET https://api.ayrshare.com/api/media/uploadUrl?fileName=test.mov&contentType=mov
  ```

  ```javascript JavaScript theme={"system"}
  const API_KEY = "Your API Key";

  fetch("https://api.ayrshare.com/api/media/uploadUrl?fileName=test.mov&contentType=mov", {
        method: "GET",
        headers: {
          "Authorization": `Bearer ${API_KEY}`
        }
      })
        .then((res) => res.json())
        .then((json) => console.log(json))
        .catch(console.error);
  ```

  ```python Python theme={"system"}
  import requests

  headers = {'Authorization': 'Bearer [API_KEY]'}

  r = requests.get('https://api.ayrshare.com/api/media/uploadUrl?fileName=test.mov&contentType=mov', headers=headers)

  print(r.json())
  ```

  ```php PHP theme={"system"}
  <?php
  require 'vendor/autoload.php';    // Composer auto-loader using Guzzle. See .../guzzlephp.org/en/stable/overview.html

  $client = new GuzzleHttp\Client();
  $res = $client->request(
      'GET',
      'https://api.ayrshare.com/api/media/uploadUrl?fileName=test.mov&contentType=mov',
      [
          'headers' => [
              'Content-Type'      => 'application/json',
              'Authorization'     => 'Bearer API_KEY'
          ]
      ]
  );

  echo json_encode(json_decode($res->getBody()), JSON_PRETTY_PRINT);
  ```

  ```csharp C# theme={"system"}
  using System;
  using System.Net.Http;
  using System.Threading.Tasks;
  using System.Web;

  namespace MediaUploadUrlGETRequest_csharp
  {
      class MediaUploadUrl
      {
          static async Task Main(string[] args)
          {
              string API_KEY = "API_KEY";
              string baseUrl = "https://api.ayrshare.com/api/media/uploadUrl";

              // Xây dựng URL với các tham số truy vấn
              var uriBuilder = new UriBuilder(baseUrl);
              var query = HttpUtility.ParseQueryString(string.Empty);
              query["fileName"] = "test.mov";
              query["contentType"] = "mov";
              uriBuilder.Query = query.ToString();

              using (var client = new HttpClient())
              {
                  client.DefaultRequestHeaders.Add("Authorization", "Bearer " + API_KEY);

                  try
                  {
                      HttpResponseMessage response = await client.GetAsync(uriBuilder.Uri);
                      response.EnsureSuccessStatusCode();
                      string responseBody = await response.Content.ReadAsStringAsync();
                      Console.WriteLine(responseBody);
                  }
                  catch (HttpRequestException e)
                  {
                      Console.WriteLine($"Error: {e.Message}");
                  }
              }
          }
      }
  }
  ```
</RequestExample>

## Chi tiết Phản hồi

<ul class="custom-bullets">
  <li>`accessUrl` là URL để truy cập tệp media sau khi tải lên.</li>

  <li>
    `contentType` là content-type được đặt cho media đang được tải lên. Sử dụng giá trị này trong header
    *Content-Type* khi tải lên media.
  </li>

  <li>`uploadUrl` là URL được sử dụng để *PUT* tệp media. Xem bên dưới.</li>
</ul>

### Các Ví dụ Endpoint Bổ sung

Quy trình để tải lên các tệp lớn hơn:

<ul class="custom-bullets">
  <li>
    Lấy `uploadURL` và `accessURL` thông qua endpoint `/media/uploadUrl`. Xem ở trên.
  </li>

  <li>Tải lên tệp thông qua một *PUT* với *Content-Type* được đặt thành `contentType` đã trả về.</li>
  <li>Tải lên media bằng cách sử dụng `--upload-file` với một tệp media và `uploadUrl`.</li>
  <li>Khi tải lên thành công, một phản hồi `200` sẽ được trả về.</li>

  <li>
    Sau khi tải lên tệp media, POST đến endpoint `/post` với `accessUrl` trong tham số body
    `mediaUrls`.
  </li>

  <li>
    **URL tải lên đã được ký sẵn chỉ có thể được tải lên một lần**. Nếu bạn gửi một tệp không hợp lệ, bạn phải
    tạo một URL tải lên mới. Sẽ không có phản hồi lỗi nếu tệp không được tải lên thành công.
    Xem bên dưới về [xác minh URL tồn tại](/apis/media/verify-media-url).
  </li>
</ul>

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X PUT \
  -H 'Content-Type: video/mp4' \
  --upload-file LOCAL_FILE_PATH uploadUrl
  ```

  ```javascript JavaScript theme={"system"}
  const fs = require("fs").promises;
  const uploadFileToSignedUrl = async (signedUrl, filePath) => {
      try {
        const fileBuffer = await fs.readFile(filePath);
        const response = await fetch(signedUrl, {
          method: "PUT",
          body: fileBuffer,
          headers: {
            "Content-Type": "video/mp4"
          }
        });

        if (response.ok) {
          console.log("File upload successful:", response.status);
        } else {
          console.error("File upload failed:", response.status);
        }
      } catch (error) {
        console.error("Error uploading file:", error);
      }
  };

  // Sử dụng URL đã được ký được tạo từ bước trước
  const signedUrl = "SIGNED_URL";
  const filePath = "LOCAL_FILE_PATH";

  uploadFileToSignedUrl(signedUrl, filePath);
  ```

  ```python Python theme={"system"}
  import requests

  def upload_file_to_signed_url(signed_url, file_path):
      try:
          with open(file_path, 'rb') as file:
              response = requests.put(signed_url, data=file, headers={'Content-Type': 'video/mp4'})

          if response.ok:
              print("File upload successful:", response.status_code)
          else:
              print("File upload failed:", response.status_code)
      except Exception as error:
          print("Error uploading file:", error)

  # Sử dụng URL đã được ký được tạo từ bước trước
  signed_url = "SIGNED_URL"
  file_path = "LOCAL_FILE_PATH"

  upload_file_to_signed_url(signed_url, file_path)
  ```

  ```php PHP theme={"system"}
  <?php

  function uploadFileToSignedUrl($signedUrl, $filePath) {
      try {
          $fileHandle = fopen($filePath, 'rb');
          if ($fileHandle === false) {
              throw new Exception('Cannot open the file');
          }

          $ch = curl_init($signedUrl);

          curl_setopt($ch, CURLOPT_PUT, true);
          curl_setopt($ch, CURLOPT_INFILE, $fileHandle);
          curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath));
          curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: video/mp4'));
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

          $response = curl_exec($ch);
          $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

          if ($httpCode == 200) {
              echo "File upload successful: " . $httpCode;
          } else {
              echo "File upload failed: " . $httpCode;
          }

          fclose($fileHandle);
          curl_close($ch);
      } catch (Exception $e) {
          echo "Error uploading file: " . $e->getMessage();
      }
  }

  // Sử dụng URL đã được ký được tạo từ bước trước
  $signedUrl = "SIGNED_URL";
  $filePath = "LOCAL_FILE_PATH";

  uploadFileToSignedUrl($signedUrl, $filePath);
  ?>

  ```

  ```csharp C# theme={"system"}
  using System;
  using System.Net.Http;
  using System.IO;
  using System.Threading.Tasks;

  class Program
  {
      static async Task Main(string[] args)
      {
          string signedUrl = "SIGNED_URL"; // Thay thế bằng URL đã ký của bạn
          string filePath = "LOCAL_FILE_PATH"; // Thay thế bằng đường dẫn tệp của bạn

          try
          {
              await UploadFileToSignedUrl(signedUrl, filePath);
          }
          catch (Exception ex)
          {
              Console.WriteLine("Error uploading file: " + ex.Message);
          }
      }

      static async Task UploadFileToSignedUrl(string signedUrl, string filePath)
      {
          using (var client = new HttpClient())
          using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
          using (var content = new StreamContent(fileStream))
          {
              content.Headers.Add("Content-Type", "video/mp4");

              var response = await client.PutAsync(signedUrl, content);

              if (response.IsSuccessStatusCode)
              {
                  Console.WriteLine("File upload successful: " + response.StatusCode);
              }
              else
              {
                  Console.WriteLine("File upload failed: " + response.StatusCode);
              }
          }
      }
  }

  ```

  ```java Java theme={"system"}
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import java.net.http.HttpRequest.BodyPublishers;
  import java.nio.file.Path;
  import java.io.IOException;
  import java.nio.file.Files;

  public class FileUploader {

      public static void main(String[] args) {
          String signedUrl = "SIGNED_URL"; // Thay thế bằng URL đã ký của bạn
          String filePath = "LOCAL_FILE_PATH"; // Thay thế bằng đường dẫn tệp của bạn

          try {
              uploadFileToSignedUrl(signedUrl, filePath);
          } catch (IOException | InterruptedException e) {
              System.out.println("Error uploading file: " + e.getMessage());
          }
      }

      private static void uploadFileToSignedUrl(String signedUrl, String filePath) throws IOException, InterruptedException {
          HttpClient client = HttpClient.newHttpClient();
          HttpRequest request = HttpRequest.newBuilder()
                  .uri(URI.create(signedUrl))
                  .header("Content-Type", "image/jpg")
                  .PUT(BodyPublishers.ofFile(Path.of(filePath)))
                  .build();

          HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

          if (response.statusCode() == 200) {
              System.out.println("File upload successful: " + response.statusCode());
          } else {
              System.out.println("File upload failed: " + response.statusCode());
          }
      }
  }

  ```
</CodeGroup>

Hãy đảm bảo rằng `contentType` được đặt khi tạo `uploadUrl` khớp với Content-Type và loại tệp khi PUT tệp.
Ví dụ, nếu bạn đặt `contentType` thành "image/png" khi tạo `uploadUrl`, hãy đảm bảo đặt `Content-Type: image/png` và tệp được tải lên kết thúc bằng `.png`.

Khi tải lên thành công, một phản hồi `200` sẽ được trả về.

### Ví dụ Tải lên Tệp Nhị phân trong Node.js

Đây là một ví dụ về việc tải lên tệp media nhị phân sử dụng Node với JavaScript:

```javascript theme={"system"}
const fs = require("fs");
const request = require("request");

const API_KEY = "Your API Key";
const fileName = "test.png";
const endpoint = `https://api.ayrshare.com/api/media/uploadUrl?fileName=${fileName}&contentType=png`;

const run = async () => {
  request.get(
    {
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${API_KEY}`
      },
      url: endpoint
    },
    (err, res, body) => {
      if (err) {
        return console.error(err);
      }

      const json = JSON.parse(body);
      console.log("Upload URL:", json);

      return fs.createReadStream(`./${fileName}`).pipe(
        request.put(
          json.uploadUrl,
          {
            headers: {
              "Content-Type": json.contentType
            }
          },
          (err, httpsResponse, body) => {
            if (err) {
              console.error("err", err);
            } else {
              console.log(body);
            }
          }
        )
      );
    }
  );
};

run();
```

### Ví dụ Tải lên Tệp Nhị phân trong Postman

Bạn cũng có thể sử dụng Postman để tải lên tệp nhị phân đến `uploadUrl`.

Trong Postman:

1. Chọn HTTP Method `PUT`.
2. Dán `uploadUrl` của bạn vào trường url. Lưu ý, url sẽ hết hạn sau một giờ và chỉ có thể được sử dụng một lần. Nếu bạn thực hiện một cuộc gọi và nó thất bại, bạn phải tạo lại `uploadUrl`.
3. Trong *Headers* đặt `Content-Type` thành content type được trả về trong endpoint /uploadUrl. Ví dụ: `Content-Type: image/png`.
4. Chọn *Body -> binary* và chọn tệp để tải lên.
5. Nhấn **Send**.
6. **Quan trọng**: Sẽ không có phản hồi trả về, vì vậy bạn nên kiểm tra xem việc tải lên có thành công hay không bằng cách mở `accessUrl` được trả về từ endpoint /uploadUrl trong trình duyệt. Bạn cũng có thể sử dụng [endpoint xác minh URL](/apis/media/verify-media-url).

<img class="center" src="https://mintcdn.com/ayrshare-docs/Nmrhj2Gh7WSf62Bh/images/apis/validate/postman%20binary.webp?fit=max&auto=format&n=Nmrhj2Gh7WSf62Bh&q=85&s=ca3def769242814afb17a58d9268667f" alt="Postman Binary Upload" width="1536" height="189" data-path="images/apis/validate/postman binary.webp" />

<Card title="Postman Sample JSON File" icon="file" href="/files/Large Media File Upload.postman_collection.json" horizontal />

<ResponseExample>
  ```javascript 200: An upload URL and access URL theme={"system"}
  {
      "accessUrl": "https://media.ayrshare.com/Aswmfs3dIEbwLSdhTlV2/test.mp4",
      "contentType": "video/mp4",
      "uploadUrl": "https://storage.googleapis.com/..."
  }
  ```

  ```json 400: Bad Request Error getting signed URL theme={"system"}
  {
    "action": "upload",
    "status": "error",
    "code": 301,
    "message": "The provided content-type 'movd' is not recognized."
  }
  ```
</ResponseExample>
