Mixpeek 비디오 임베딩 연동

Mixpeek 비디오 임베딩 연동 (mixpeek)

Mixpeek의 비디오 처리 기능은 비디오를 청크(chunk)로 나누고 임베딩하는 역할을 하고, Qdrant는 이 임베딩들을 효율적으로 저장하고 검색하는 역할을 해요. 비디오 검색 파이프라인을 구축할 때 한쪽은 전처리, 한쪽은 저장·검색으로 역할을 나눠서 쓰는 구성이에요.

출처: Qdrant 공식 문서 — mixpeek

사전 준비 (Prerequisites)

  • Python 3.7+
  • Mixpeek API key
  • Mixpeek 클라이언트 설치 (pip install mixpeek)
  • Qdrant 클라이언트 설치 (pip install qdrant-client)

설치 (Installation)

  1. 필요한 패키지를 설치해요.
pip install mixpeek qdrant-client
  1. Mixpeek API key를 설정해요.
from mixpeek import Mixpeek

mixpeek = Mixpeek('your_api_key_here')
  1. Qdrant 클라이언트를 초기화해요.
from qdrant_client import QdrantClient

client = QdrantClient("localhost", port=6333)

사용 방법 (Usage)

1. Qdrant 컬렉션 만들기

벡터를 삽입하기 전에 Qdrant 컬렉션을 먼저 만들어야 해요. "vuse-generic-v1" 모델에 맞는 벡터 크기(768)로 컬렉션을 만들 수 있어요.

client.create_collection(
    collection_name="video_chunks",
    vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE)
)

2. 비디오 처리 및 임베딩

먼저 비디오를 청크로 처리하고, 각 청크를 임베딩해요.

from mixpeek import Mixpeek
from qdrant_client import QdrantClient, models

mixpeek = Mixpeek('your_api_key_here')
client = QdrantClient("localhost", port=6333)

video_url = "https://mixpeek-public-demo.s3.us-east-2.amazonaws.com/starter/jurassic_park_trailer.mp4"

# 비디오를 청크로 처리
processed_chunks = mixpeek.tools.video.process(
    video_source=video_url,
    chunk_interval=1,  # 1초 간격
    resolution=[720, 1280]
)

# 각 청크를 임베딩하고 Qdrant에 삽입
for index, chunk in enumerate(processed_chunks):
    print(f"Processing video chunk: {index}")

    embedding = mixpeek.embed.video(
        model_id="vuse-generic-v1",
        input=chunk['base64_chunk'],
        input_type="base64"
    )['embedding']

    # Qdrant에 삽입
    client.upsert(
        collection_name="video_chunks",
        points=[models.PointStruct(
            id=index,
            vector=embedding,
            payload={
                "start_time": chunk["start_time"],
                "end_time": chunk["end_time"]
            }
        )]
    )

    print(f"  Embedding preview: {embedding[:5] + ['...'] + embedding[-5:]}")

print(f"Processed and inserted {len(processed_chunks)} chunks")

chunk_interval=1은 1초 단위로 비디오를 자르라는 뜻이에요. 각 청크에는 start_time, end_time이 payload로 함께 저장돼서, 검색 결과에서 어떤 구간에 해당하는지 바로 알 수 있어요.

3. 유사한 비디오 청크 검색하기

유사한 비디오 청크를 검색하려면 텍스트 쿼리나 비디오 쿼리를 사용할 수 있어요.

텍스트 쿼리 (Text Query)

query_text = "a car chase scene"

# 텍스트 쿼리를 임베딩
query_embedding = mixpeek.embed.video(
    model_id="vuse-generic-v1",
    input=query_text,
    input_type="text"
)['embedding']

# Qdrant에서 검색
search_results = client.query_points(
    collection_name="video_chunks",
    query=query_embedding,
    limit=5
).points

for result in search_results:
    print(f"Chunk ID: {result.id}, Score: {result.score}")
    print(f"Time range: {result.payload['start_time']} - {result.payload['end_time']}")

비디오 쿼리 (Video Query)

query_video_url = "https://mixpeek-public-demo.s3.us-east-2.amazonaws.com/starter/jurassic_bunny.mp4"

# 비디오 쿼리를 임베딩
query_embedding = mixpeek.embed.video(
    model_id="vuse-generic-v1",
    input=query_video_url,
    input_type="url"
)['embedding']

# Qdrant에서 검색
search_results = client.query_points(
    collection_name="video_chunks",
    query=query_embedding,
    limit=5
).points

for result in search_results:
    print(f"Chunk ID: {result.id}, Score: {result.score}")
    print(f"Time range: {result.payload['start_time']} - {result.payload['end_time']}")

두 경우 모두 검색 쿼리를 임베딩한 뒤 query_points로 비슷한 청크를 찾아요. 차이는 쿼리 입력이 텍스트냐 비디오 URL이냐일 뿐이에요.

리소스 (Resources)

Mixpeek Embed에 대한 더 자세한 정보는 공식 문서를 참고하세요: https://docs.mixpeek.com/api-documentation/inference/embed

더 알아보기 (Learn more)