> ## Documentation Index
> Fetch the complete documentation index at: https://learn.social.plus/llms.txt
> Use this file to discover all available pages before exploring further.

# Video Handling

> Upload videos and read transcoding status or resolution URLs with the Social+ SDKs.

Use video handling when your app needs to upload video files for posts, messages, stories, clips, or other media experiences. Video uploads return a video file object with a `fileId`, original URL, and, on platforms that expose it, transcoding status and a map of generated resolution URLs.

The SDK exposes upload progress and video file metadata. Playback UI, caching, retry policy, and adaptive player behavior remain application concerns.

## Platform Surface

| Platform   | Upload                                                                                                  | Fetch                                                                          | Status and resolutions                                                       | Notes                                                                                                        |
| ---------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| TypeScript | `FileRepository.uploadVideo(formData, feedType?, onProgress?)`                                          | `FileRepository.getFile(fileId)`                                               | `status` and `videoUrl` on the returned file                                 | `ContentFeedType` includes `story`, `clip`, `chat`, `post`, and `message`.                                   |
| iOS        | `AmityFileRepository.uploadVideo(with:progress:)` and `uploadVideo(with:feedType:progress:completion:)` | `getFile(fileId:)`, then `mapToVideoData()`                                    | `AmityVideoData.status`, `videoUrls`, and `getVideo(resolution:)`            | The async upload method checks for files over 1 GB. The feed-type callback overload checks 4 GB and 2 hours. |
| Android    | `AmityCoreClient.newFileRepository().uploadVideo(uri, contentFeedType)`                                 | `getFile(fileId)`, then `asAmityVideo()`                                       | `getStatus()`, `getResolutions()`, and `getVideoUrl(resolution)`             | `AmityContentFeedType` exposes `STORY`, `CLIP`, `MESSAGE`, and `POST`.                                       |
| Flutter    | `AmityCoreClient.newFileRepository().uploadVideo(file, feedtype?)`                                      | Not exposed as a direct public file-repository fetch method in the current SDK | `AmityVideo.getResolutions()` and `getVideoUrl(resolution)` on video objects | `AmityContentFeedType` exposes `STORY`, `POST`, `MESSAGE`, and `CLIP`.                                       |

## Parameters

| Parameter                                   | Platforms                         | Description                                                                                                                                        |
| ------------------------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `formData` / `url` / `uri` / `file`         | TypeScript, iOS, Android, Flutter | The local video input. TypeScript expects `FormData` with a `files` key; iOS accepts a local `URL`; Android accepts `Uri`; Flutter accepts `File`. |
| `feedType` / `contentFeedType` / `feedtype` | TypeScript, iOS, Android, Flutter | Optional or required video context depending on platform. It tells the backend which content surface the video is for.                             |
| `fileId`                                    | TypeScript, iOS, Android          | ID returned by upload or embedded in content data. Used for direct fetch where available.                                                          |
| `resolution`                                | TypeScript, iOS, Android, Flutter | Requested generated video URL. Exposed values include original, 1080p, 720p, 480p, and 360p where available for that upload.                       |
| `onProgress` / `progress`                   | TypeScript, iOS, Android, Flutter | Upload progress callback or stream event.                                                                                                          |

## Upload A Video

Upload a video first, then use the returned video object or `fileId` in video-based content APIs.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { ContentFeedType, FileRepository } from '@amityco/ts-sdk';

  async function uploadVideo(video: File) {
    const formData = new FormData();
    formData.append('files', video);

    const { data: videos } = await FileRepository.uploadVideo(
      formData,
      ContentFeedType.POST,
      percent => {
        console.log(`Upload progress: ${percent}%`);
      },
    );

    return videos[0].fileId;
  }
  ```

  ```swift iOS theme={null}
  let videoURL = URL(fileURLWithPath: "/tmp/video.mov")

  let uploadedVideo = try await fileRepository.uploadVideo(
      with: videoURL,
      progress: { progress in
          print("Upload progress: \(progress)")
      }
  )

  let videoFileId = uploadedVideo.fileId
  ```

  ```kotlin Android theme={null}
  val videoUri = Uri.parse("file:///tmp/video.mp4")

  AmityCoreClient.newFileRepository()
      .uploadVideo(
          uri = videoUri,
          contentFeedType = AmityContentFeedType.POST
      )
      .doOnNext { result: AmityUploadResult<AmityVideo> ->
          when (result) {
              is AmityUploadResult.PROGRESS -> {
                  val progress = result.getUploadInfo().getProgressPercentage()
              }
              is AmityUploadResult.COMPLETE -> {
                  val uploadedVideo = result.getFile()
                  val videoFileId = uploadedVideo.getFileId()
              }
              is AmityUploadResult.ERROR -> {
                  val error = AmityError.from(result.getError())
              }
              is AmityUploadResult.CANCELLED -> {
                  // Upload was canceled.
              }
          }
      }
      .subscribe()
  ```

  ```dart Flutter theme={null}
  import 'dart:io';

  final video = File('/tmp/video.mp4');

  AmityCoreClient.newFileRepository()
      .uploadVideo(video, feedtype: AmityContentFeedType.POST)
      .stream
      .listen((AmityUploadResult<AmityVideo> result) {
    result.when(
      progress: (uploadInfo, cancelToken) {
        final progress = uploadInfo.getProgressPercentage();
      },
      complete: (uploadedVideo) {
        final videoFileId = uploadedVideo.fileId;
        final resolutions = uploadedVideo.getResolutions();
      },
      error: (error) {
        final exception = error;
      },
      cancel: () {
        // Upload was canceled.
      },
    );
  });
  ```
</CodeGroup>

## Read Video Status And URLs

Read video status and resolution URLs when your UI needs to render playback or processing state.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { FileRepository } from '@amityco/ts-sdk';

  async function getVideo(videoFileId: string) {
    const { data: video } = await FileRepository.getFile<'video'>(videoFileId);
    const playbackUrl = video.videoUrl?.['720p'] ?? video.fileUrl;

    return {
      playbackUrl,
      status: video.status,
    };
  }
  ```

  ```swift iOS theme={null}
  let rawFile = try await fileRepository.getFile(fileId: videoFileId)

  if rawFile.type == .video, let videoData = rawFile.mapToVideoData() {
      let status = videoData.status
      let resolutions = Array(videoData.videoUrls.keys).sorted()
      let playbackURL = videoData.getVideo(resolution: .res_720p)
  }
  ```

  ```kotlin Android theme={null}
  AmityCoreClient.newFileRepository()
      .getFile(videoFileId)
      .doOnSuccess { rawFile: AmityRawFile ->
          val video = rawFile.asAmityVideo()
          val status = video?.getStatus()
          val resolutions = video?.getResolutions().orEmpty()
          val playbackUrl = video?.getVideoUrl(AmityVideoResolution.RES_720)
      }
      .subscribe()
  ```

  ```dart Flutter theme={null}
  void inspectVideo(AmityVideo video) {
    final resolutions = video.getResolutions();
    final playbackUrl = video.getVideoUrl(AmityVideoResolution.RES_720);
  }
  ```
</CodeGroup>

## Related Topics

<CardGroup cols={3}>
  <Card title="Video Posts" icon="video" href="/social-plus-sdk/social/content-management/posts/creation/video-post">
    Attach uploaded videos to social posts.
  </Card>

  <Card title="File Handling" icon="file" href="./file">
    Upload and inspect generic file attachments.
  </Card>

  <Card title="Clip Posts" icon="clapperboard" href="/social-plus-sdk/social/content-management/posts/creation/clip-post">
    Create short-form clip posts where supported.
  </Card>
</CardGroup>
