# Video

<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

This section describes how to render video.

## Render the video view

The Video SDK for Flutter uses two different widgets to render video.

-   For Android it uses `AndroidView`.
-   For iOS it uses `UiKitView`.

Define a `View` class to render the video view for both of these platforms:

```dart
switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        return AndroidView(
          viewType: 'the name of view type',
          layoutDirection: TextDirection.ltr,
          creationParams: creationParams,
          creationParamsCodec: const StandardMessageCodec(),
        );
      case TargetPlatform.iOS:
        return UiKitView(
          viewType: 'the name of view type',
          layoutDirection: TextDirection.ltr,
          creationParams: creationParams,
          creationParamsCodec: const StandardMessageCodec(),
        );
      default:
        throw UnsupportedError("Unsupported platform");
    }
```

## Separate full screen and horizontal scrolling list views

To separate the full screen view and horizontal scrolling list view, define another class, `VideoView`, to render the `View` based on whether it is full screen or not:

```dart
class VideoView extends HookWidget {
  final ZoomVideoSdkUser? user;
  final bool sharing;
  final bool preview;
  final bool focused;
  final bool hasMultiCamera;
  final String multiCameraIndex;
  final String? videoAspect;
  final bool fullScreen;

  const VideoView({
    super.key,
    required this.user,
    required this.sharing,
    required this.preview,
    required this.focused,
    required this.hasMultiCamera,
    required this.multiCameraIndex,
    this.videoAspect,
    required this.fullScreen,
  });
}
```

In the example app file, `lib/call-screen.dart`, the function returns `VideoView` in two separate code blocks:

-   one for full screen visualization and
-   the other for a horizontally scrolling list of remote users in a video session at the bottom of the screen.

## Full screen visualization

The full screen visualization, upon initialization with video enabled, renders what others participating in a video session see:

```dart
fullScreenView = AnimatedOpacity(
  opacity: opacityLevel,
  duration: const Duration(seconds: 3),
  child: VideoView(
    user: fullScreenUser.value,
    hasMultiCamera: false,
    sharing: sharingUser.value == null
        ? false
        : (sharingUser.value?.userId == fullScreenUser.value?.userId),
    preview: false,
    focused: false,
    multiCameraIndex: "0",
    videoAspect: VideoAspect.Original,
    fullScreen: true,
  ),
);
```

### Creation parameters passed to `View`

This function passes the following parameters to `View`:

-   `user`: A `ZoomVideoSdkUser` type instantiated via an event listener for Video SDK session when a user creates, joins, or leaves a session.
-   `sharing`: A Boolean set to `true` if the current full screen user is currently the user who is sharing a screen with others.
-   `preview`: A Boolean set to `true` if the video view is for preview.
-   `hasMultiCamera`: A Boolean set to `true` if the user's device has more than one camera.
-   `multiCameraIndex`: The index of camera view that the `View` should render.
-   `videoAspect`: The aspect ratio.
-   `fullScreen`: A Boolean value that tells the `View` component to render itself full screen or horizontal `ListView`.

## Horizontally scrolling list

At the bottom of the call-screen, users can see a horizontally scrolling list of other users in the call. Use `VideoView` in the horizontal `ListView` that renders this as well:

```dart
Container(
  height: 110,
  margin: const EdgeInsets.only(left: 20, right: 20),
  alignment: Alignment.center,
  child: ListView.separated(
    scrollDirection: Axis.horizontal,
    itemCount: users.value.length,
    itemBuilder: (BuildContext context, int index) {
      return InkWell(
        onTap: () async {
          onSelectedUser(users.value[index]);
        },
        child: Center(
          child: VideoView(
            user: users.value[index],
            hasMultiCamera: false,
            sharing: sharingUser.value == null
                ? false
                : sharingUser.value?.userId == users.value[index].userId,
            preview: false,
            focused: false,
            multiCameraIndex: "0",
            videoAspect: VideoAspect.Original,
            fullScreen: false,
          ),
        ),
      );
    },
    separatorBuilder: (BuildContext context, int index) =>
        const Divider(),
  ),
);
```

The horizontally scrolling `ListView` at the bottom of the screen renders mini video screens for all users in a session. Tapping a remote user's screen sets that user to the full screen user.

## Use virtual background

Use [`ZoomVideoSdkVirtualBackgroundHelper`](https://marketplacefront.zoom.us/sdk/custom/flutter/native_zoom_videosdk_virtual_background_helper/ZoomVideoSdkVirtualBackgroundHelper-class.html) to enable virtual backgrounds. First determine whether the device supports it using `isSupportVirtualBackground`. If the device supports it, use the helper functions to add, get, set, and remove virtual backgrounds.

To add virtual backgrounds:

1. Use `addVirtualBackgroundItem` to add a virtual background item.
2. Use `getVirtualBackgroundItemList` to get a list of available virtual background items.
3. Choose a virtual background item from the list and use `setVirtualBackgroundItem` to set the virtual background.

Use `removeVirtualBackgroundItem` to remove the virtual background or set the virtual background to None. Use `getSelectedVirtualBackgroundItem` to get the current selected background.

```dart
// Check if virtual background is supported
@override
Future<bool> isSupportVirtualBackground() async {
  return await methodChannel
      .invokeMethod<bool>('isSupportVirtualBackground')
      .then<bool>((bool? value) => value ?? false);
}

// Add virtual background item
@override
Future<ZoomVideoSdkVirtualBackgroundItem?> addVirtualBackgroundItem(String filePath) async {
  var params = <String, dynamic>{};
  params.putIfAbsent("filePath", () => filePath);

  var itemString = await methodChannel
      .invokeMethod<String>('addVirtualBackgroundItem', params)
      .then<String>((String? value) => value ?? "");

  Map<String, dynamic> itemMap = jsonDecode(itemString!);
  var vbItem =
  ZoomVideoSdkVirtualBackgroundItem.fromJson(itemMap);
  return vbItem;
}

// Remove virtual background item
@override
Future<String> removeVirtualBackgroundItem(String imageName) async {
  var params = <String, dynamic>{};
  params.putIfAbsent("imageName", () => imageName);

  return await methodChannel
      .invokeMethod<String>('removeVirtualBackgroundItem', params)
      .then<String>((String? value) => value ?? "");
}

// Get virtual background item list
@override
Future<List<ZoomVideoSdkVirtualBackgroundItem>> getVirtualBackgroundItemList() async {
  var itemListString = await methodChannel
      .invokeMethod<String?>('getVirtualBackgroundItemList')
      .then<String?>((String? value) => value);

  var itemListJson = jsonDecode(itemListString!) as List;
  List<ZoomVideoSdkVirtualBackgroundItem> itemList = itemListJson
      .map((languageJson) =>
      ZoomVideoSdkVirtualBackgroundItem.fromJson(languageJson))
      .toList();

  return itemList;
}

// Set virtual background item
@override
Future<String> setVirtualBackgroundItem(String imageName) async {
  var params = <String, dynamic>{};
  params.putIfAbsent("imageName", () => imageName);

  return await methodChannel
      .invokeMethod<String>('setVirtualBackgroundItem', params)
      .then<String>((String? value) => value ?? "");
}

// Get selected virtual background
@override
Future<ZoomVideoSdkVirtualBackgroundItem> getSelectedVirtualBackgroundItem() async {

}
```
