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

# 동영상 이해

> AIHubMix의 Chat Completions 및 Responses API로 Qwen3.7 Plus를 호출하여 공개 또는 로컬 MP4 동영상에서 장면 설명, 이벤트 타임스탬프, JSON 결과를 얻습니다.

<h2 id="overview">
  개요
</h2>

동영상 이해는 모델이 동영상 프레임과 텍스트 지시를 분석하고 설명, 타임스탬프 또는 구조화된 결과를 반환하는 기능입니다. 주요 용도는 다음과 같습니다.

* 장면 및 인물 행동 설명
* 동영상 요약 및 내용에 대한 질의응답
* 이벤트 시작 및 종료 시점 찾기
* JSON 형식의 정보 추출

이 가이드에서는 `qwen3.7-plus`를 예로 들어 Chat Completions와 Responses API의 MP4 입력 방법을 설명합니다.

<h2 id="protocols">
  API 및 입력 형식
</h2>

| 모델 및 엔드포인트 | 동영상 콘텐츠 필드 | JSON 출력 매개변수 |
| - | - | - |
| `qwen3.7-plus`, `/v1/chat/completions` | `messages[].content[]`의 `video_url` | `response_format.type = "json_object"` |
| `qwen3.7-plus`, `/v1/responses` | `input[].content[]`의 `video_url` | `text.format.type = "json_object"` |

Responses의 `video_url`은 AIHubMix 확장 필드입니다. 아래 예제에서는 HTTP 요청으로 전달합니다.

Gemini 모델의 멀티미디어 입력 방법은 [Gemini 가이드](/ko/api/Gemini-Guides)를 참조하세요.

<h2 id="chat-url">
  빠른 시작
</h2>

다음 예제는 Node.js 22의 내장 `fetch`를 사용하므로 SDK 설치가 필요하지 않습니다. 실행 전에 환경 변수 `AIHUBMIX_API_KEY`를 설정하세요. 예제 URL은 Alibaba 공식 문서의 공개 MP4입니다. 실제 서비스에서는 `url`을 모델 프로바이더가 접근할 수 있는 동영상 주소로 바꾸세요.

<CodeGroup>
  ```javascript Chat 공개 MP4 theme={null}
  const response = await fetch("https://aihubmix.com/v1/chat/completions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.AIHUBMIX_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "qwen3.7-plus",
      enable_thinking: false,
      max_tokens: 800,
      response_format: { type: "json_object" },
      messages: [{
        role: "user",
        content: [
          {
            type: "video_url",
            video_url: {
              url: "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241115/cqqkru/1.mp4",
            },
          },
          {
            type: "text",
            text: 'Analyze the attached video. Return a JSON object with a scenes array. Each scene must contain start_seconds, end_seconds and description. If no video is available, return {"error":"no_video"}.',
          },
        ],
      }],
    }),
    signal: AbortSignal.timeout(120000),
  });
  const result = await response.json();
  if (!response.ok) throw new Error(JSON.stringify(result));
  const scenes = JSON.parse(result.choices[0].message.content);
  console.log(JSON.stringify({
    request_id: response.headers.get("x-aihubmix-request-id"),
    result: scenes,
    usage: result.usage,
  }, null, 2));
  ```
</CodeGroup>

코드를 `.mjs` 파일로 저장한 뒤 Node.js로 실행하세요. 성공 결과는 `choices[0].message.content`에 있으며 JSON으로 한 번 더 파싱해야 합니다. 예제는 콘솔에서 확인할 수 있도록 요청 ID와 사용량도 출력합니다.

<h2 id="chat-base64">
  로컬 동영상 입력
</h2>

로컬 파일을 Base64로 인코딩한 뒤 `data:video/mp4;base64,` 데이터 URL로 전달합니다. 다음 예제는 첫 번째 명령줄 인수에서 파일 경로를 읽으며, 인수가 없으면 현재 디렉터리의 `video.mp4`를 읽습니다. HTTP 요청의 동영상 URL에 로컬 파일 경로를 직접 사용할 수 없습니다.

<CodeGroup>
  ```javascript Chat 로컬 MP4 theme={null}
  import { readFileSync } from "node:fs";

  const video = readFileSync(process.argv[2] ?? "video.mp4").toString("base64");
  const response = await fetch("https://aihubmix.com/v1/chat/completions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.AIHUBMIX_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "qwen3.7-plus",
      enable_thinking: false,
      max_tokens: 800,
      response_format: { type: "json_object" },
      messages: [{
        role: "user",
        content: [
          {
            type: "video_url",
            video_url: { url: `data:video/mp4;base64,${video}` },
          },
          {
            type: "text",
            text: 'Analyze the attached video. Return a JSON object with a scenes array. Each scene must contain start_seconds, end_seconds and description. If no video is available, return {"error":"no_video"}.',
          },
        ],
      }],
    }),
    signal: AbortSignal.timeout(120000),
  });
  const result = await response.json();
  if (!response.ok) throw new Error(JSON.stringify(result));
  const scenes = JSON.parse(result.choices[0].message.content);
  console.log(JSON.stringify({
    request_id: response.headers.get("x-aihubmix-request-id"),
    result: scenes,
    usage: result.usage,
  }, null, 2));
  ```
</CodeGroup>

<h2 id="responses">
  Responses API
</h2>

Responses 요청에서도 `video_url` 객체를 사용하며 텍스트 블록에는 `input_text`를 지정합니다. JSON 출력 설정은 `text.format` 아래에 둡니다. 이 예제도 첫 번째 명령줄 인수 또는 현재 디렉터리의 `video.mp4`에서 동영상을 읽습니다.

<CodeGroup>
  ```javascript Responses 로컬 MP4 theme={null}
  import { readFileSync } from "node:fs";

  const video = readFileSync(process.argv[2] ?? "video.mp4").toString("base64");
  const response = await fetch("https://aihubmix.com/v1/responses", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.AIHUBMIX_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "qwen3.7-plus",
      max_output_tokens: 800,
      text: { format: { type: "json_object" } },
      input: [{
        role: "user",
        content: [
          {
            type: "video_url",
            video_url: { url: `data:video/mp4;base64,${video}` },
          },
          {
            type: "input_text",
            text: 'Analyze the attached video. Return a JSON object with a scenes array. Each scene must contain start_seconds, end_seconds and description. If no video is available, return {"error":"no_video"}.',
          },
        ],
      }],
    }),
    signal: AbortSignal.timeout(120000),
  });
  const result = await response.json();
  if (!response.ok || result.status !== "completed") {
    throw new Error(JSON.stringify(result));
  }
  const text = result.output
    .filter((item) => item.type === "message")
    .flatMap((item) => item.content)
    .filter((part) => part.type === "output_text")
    .map((part) => part.text)
    .join("");
  console.log(JSON.stringify({
    request_id: response.headers.get("x-aihubmix-request-id"),
    result: JSON.parse(text),
    usage: result.usage,
  }, null, 2));
  ```
</CodeGroup>

Responses의 `output`에는 추론 항목과 메시지 항목이 함께 포함될 수 있습니다. 결과를 읽을 때는 `message`의 `output_text`를 선택하세요. 출력 사용량에는 추론 토큰이 포함될 수 있으므로 최종 JSON 길이만으로 비용을 추정할 수 없습니다.

<h2 id="structured-output">
  구조화된 출력
</h2>

예제는 JSON 모드로 `scenes` 배열을 반환합니다. 각 장면에는 다음 필드가 포함됩니다.

| 필드 | 유형 | 설명 |
| - | - | - |
| `start_seconds` | 숫자 | 장면 시작 시간, 단위는 초 |
| `end_seconds` | 숫자 | 장면 종료 시간, 단위는 초 |
| `description` | 문자열 | 장면 내용 설명 |

애플리케이션 요구 사항에 맞게 프롬프트와 필드를 조정할 수 있습니다. JSON 모드는 JSON 출력을 보장하며, 필드 유형, 필수 항목, 시간 범위는 애플리케이션에서 검증해야 합니다.

<h2 id="limits">
  파일 및 길이 제한
</h2>

[Alibaba 공식 시각 이해 문서](https://help.aliyun.com/zh/model-studio/vision)에 명시된 Qwen3.7 시리즈의 동영상 제한은 다음과 같습니다.

* 동영상 형식에는 MP4, AVI, MKV, MOV, FLV, WMV가 포함됩니다.
* 동영상 길이는 2초부터 2시간까지입니다.
* Base64로 인코딩된 문자열은 10MB 미만이어야 하며, 원본 파일은 7MB 미만을 권장합니다.
* 공개 URL 방식의 프로바이더 파일 크기 상한은 2GB입니다.

Base64는 요청 크기를 증가시킵니다. 큰 파일에는 공개 동영상 URL을 우선 사용하고, 전체 요청 과정에서 링크가 유효한지 확인하세요.

<h2 id="billing">
  요금 및 토큰
</h2>

Qwen은 동영상 프레임을 입력 토큰으로 변환하여 프롬프트와 함께 입력 사용량에 포함합니다. 모델이 생성한 콘텐츠는 출력 사용량에 포함됩니다. 동영상 길이, 해상도, 프레임 추출 방식이 사용량에 영향을 주므로 MP4 파일 크기나 초 단위 길이만으로 비용을 계산할 수 없습니다.

Qwen3.7 Plus의 동영상 입력에는 모델의 입력 토큰 단가가, 생성 콘텐츠에는 출력 토큰 단가가 적용됩니다. 가격은 [Qwen3.7 Plus 모델 페이지](https://aihubmix.com/model/qwen3.7-plus)를 참조하세요.

* Chat Completions 사용량 필드는 `usage.prompt_tokens`와 `usage.completion_tokens`입니다.
* Responses 사용량 필드는 `usage.input_tokens`와 `usage.output_tokens`입니다.
* 추론 토큰은 출력 토큰에 이미 포함되므로 다시 더하지 않습니다.
* 캐시 적중 부분에는 해당 캐시 요금이 적용됩니다.

콘솔에서 각 요청의 토큰 사용량과 요금을 확인할 수 있습니다. 특정 요청을 조사할 때는 응답 헤더의 `x-aihubmix-request-id`를 보관하세요.

<h2 id="usage-tips">
  사용 권장 사항
</h2>

* 동영상과 텍스트 지시를 함께 보내고 추출할 내용과 출력 형식을 명확히 지정하세요.
* 공개 동영상 링크는 요청 중 유효해야 하며 모델 프로바이더가 접근할 수 있어야 합니다.
* 작은 로컬 파일에는 Base64를, 큰 파일에는 공개 URL을 우선 사용하세요.
* 애플리케이션에서 JSON 필드, 장면 순서, 시간 범위를 검증하세요.
* 타임스탬프는 이벤트 위치 파악과 콘텐츠 검색에 적합합니다. 정밀 편집이 필요하면 동영상 처리 도구로 경계를 보정하세요.

***

업데이트: 2026-10-13


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.