
チュートリアル
ビデオコンテンツからインタラクティブな学習アプリを構築する

リシケシュ・ヤダフ
このチュートリアルでは、Twelve LabsのAnalyze API(Pegasus 1.2搭載)を使用して教育用ビデオからコンテンツを抽出し、SambaNovaのDeepSeekモデルを使用してそのコンテンツに基づいたプレイ可能なインタラクティブHTMLゲームを生成する、Video2Gameアプリケーションの構築プロセスを詳しく説明します。
このチュートリアルでは、Twelve LabsのAnalyze API(Pegasus 1.2搭載)を使用して教育用ビデオからコンテンツを抽出し、SambaNovaのDeepSeekモデルを使用してそのコンテンツに基づいたプレイ可能なインタラクティブHTMLゲームを生成する、Video2Gameアプリケーションの構築プロセスを詳しく説明します。

この記事の内容
No headings found on page
ニュースレターに登録する
ニュースレターに登録する
ビデオ理解に関する最新の技術進歩、チュートリアル、業界の動向をお届けします
ビデオ理解に関する最新の技術進歩、チュートリアル、業界の動向をお届けします
AIを活用してビデオを検索、分析、探索します。
2025/08/12
13分
記事へのリンクをコピー
u306fu3058u3081u306b
u6559u80b2u30d2u30c7u30aau304cu5358u306bu898bu305bu3066u4f1du3048u308bu3060u3051u3067u306fu306au304fu3001u305du308cu4ee5u4e0au306eu3053u3068u304cu3067u304du308bu3068u3057u305fu3089u3069u3046u3067u3057u3087u3046uff1f ud83cudfae
u53d7u52d5u7684u306au30d2u30c7u30aau8b1bu7fa9u3092u3001u53d7u8b1bu751fu304cu5358u306bu8996u8074u3059u308bu306eu3067u306fu306au304fu3001u30b3u30f3u30bbu30d7u30c8u3092u30d7u30ecu30a4u3057u306au304cu3089u5b66u3076u3001u53ccu65b9u5411u306eu30deu30fcu30e0u30d9u30fcu30b9u306eu5b66u7fd2u4f53u9a13u306bu5909u3048u308bu3053u3068u3092u60f3u50cfu3057u3066u307fu3066u304fu3060u3055u3044u3002
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001TwelveLabsu3092u6d3bu7528u3057u3066u3001YouTubeu306eu6559u80b2u30d2u30c7u30aau3092u9b45u529bu7684u306au5b66u7fd2u30deu30fcu30e0u306bu5909u63dbu3059u308bu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u69cbu7bc9u3057u307eu3059u3002TwelveLabsu30a2u30cau30e9u30a4u30bau30a8u30f3u30b8u30f3u3068u3001SambaNovau306eu63a8u8ad6u30e2u30c7u30ebu3092u7d44u307fu5408u308fu305bu308bu3053u3068u3067u3001u30d2u30c7u30aau304bu3089u6709u610fu7fa9u306au30b3u30f3u30c6u30f3u30c4u3092u62bdu51fau3057u3001u305du308cu3092u53ccu65b9u5411u306eu5b66u7fd2u30e2u30b8u30e5u30fcu30ebu306bu5909u63dbu3059u308bu3053u3068u304cu3067u304du307eu3059u3002
Video2Gameu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u304cu3069u306eu3088u3046u306bu52d5u4f5cu3059u308bu306eu304bu3001u305du3057u3066TwelveLabs Python SDKu3068SambaNovau3092u4f7fu7528u3057u3066u3001u30d2u30c7u30aau7406u89e3u3068u9ad8u901fu63a8u8ad6LLMu3092u7528u3044u305fu540cu69d8u306eu30bdu30eau30e5u30fcu30b7u30e7u30f3u3092u3069u306eu3088u3046u306bu69cbu7bc9u3067u304du308bu304bu3092u63a2u3063u3066u307fu307eu3057u3083u3046u3002
u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30c7u30e2u306fu3053u3061u3089u3067u4f53u9a13u3067u304du307eu3059uff1aVideo2Gameu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3
u524du63d0u6761u4ef6
TwelveLabs Playgroundu306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3066u3001APIu30adu30fcu3092u767au884cu3057u307eu3059u3002
SambaNovau306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3001u30e2u30c7u30ebu306bu30a2u30afu30bbu30b9u3059u308bu305fu3081u306eAPIu30adu30fcu3092u767au884cu3057u307eu3059u3002
u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30eau30ddu30b8u30c8u30eau306fu3001GitHubu30eau30ddu30b8u30c8u30eau3067u78bau8a8du3067u304du307eu3059u3002
Pythonu3001Flasku3001u304au3088u3073Next.jsu306bu7cbeu901au3057u3066u3044u308bu3053u306eu304cu671bu307eu3057u3044u3067u3059u3002
u30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3
u3053u306eu30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u5206u6790u3059u308bu3053u3068u3067u30d2u30c7u30aau7406u89e3u3092u793au3057u3001u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4f5cu6210u3092u652fu63b4u3057u307eu3059u3002u3053u308cu306fu3001u9ad8u901fu63a8u8ad6LLMu306eu30b3u30fcu30c9u751fu6210u306bu3088u3063u3067u884cu308fu308cu307eu3059u3002u30e2u30fcu30b6u30fcu306fu3001TwelveLabsu306eAPIu30adu30fcu3092u63a5u7d9au3059u308bu3053u3068u3067u3001u30d2u30c7u30aau306eURLu3092u63d0u4f9bu3059u308bu304bu3001u307eu305fu306fu3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu30d2u30c7u30aau304bu3089u76f4u63a5u30d2u30c7u30aau3092u9078u629eu3067u304du307eu3059u3002
u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu76eeu7684u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u304bu3089u306eu53ceu30bcu3068u53ccu65b9u5411u6027u3092u5099u3048u305fu65b0u3057u3044u5b66u7fd2u4f53u9a13u3092u63d0u4f9bu3059u308bu3053u3068u3067u3059u3002u3053u3061u3089u3067u3001u30b3u30fcu30c9u306eu8a73u7d30u306au8aacu660eu3068u30c7u30e2u3092u3054u89a7u3044u305fu3060u3051u307eu3059 u2014

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4ed5u7d44u307f
u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f2u3064u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u30e2u30fcu30c9u3092u30b5u30ddu30fcu30c8u3057u3066u3044u307eu3059 u2014
YouTubeu52d5u753bURLu3092u4f7fu7528u3059u308bu5834u5408uff1aYouTubeu52d5u753bu306eURLu3092u63d0u4f9bu3059u308bu3068u3001u30b7u30b9u30c6u30e0u304cu52d5u753bu3092u51e6u7406u30fbu5206u6790u3057u3001SambaNovau3092u4f7fu7528u3057u305fu9ad8u901fu63a8u8ad6LLMu30e2u30c7u30ebu306bu3088u3063u3066u3001u52d5u753bu306bu57fau3065u304fu53ccu65b9u5411u306eu30b2u30fcu30e0u578bu5b66u7fd2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u81eau52d5u751fu6210u3057u307eu3059u3002
TwelveLabs APIu30adu30fcu3092u4f7fu7528u3059u308bu5834u5408uff1au500bu4ebau306eTwelveLabs APIu30adu30fcu3092u63a5u7d9au3057u3066u3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu306fu3058u3081u3066u3044u308bu81eau8eabu306eu52d5u753bu306bu30a2u30afu30bbu30b9u3057u3001u64cdu4f5cu3057u307eu3059u3002u63a5u7d9au3059u308bu3068u3001u65e2u5b58u306eu30a4u30f3u30c7u30c3u30afu30b9IDu3068u5bfeu5fdcu3059u308bu52d5u753bu3092u9078u629eu3067u304du3001u30b7u30b9u30c6u30e0u306fu9078u629eu3055u308cu305fu52d5u753bu30b3u30f3u200bu200bu30c6u30f3u30c4u306bu57fau3065u304fu53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u751fu6210u3057u307eu3059u3002
YouTubeu306eURLu304cu63d0u4f9bu3055u308cu308bu3068u3001u30d2u30c7u30aau306fu307eu305au51e6u7406u3055u308cu3001u30edu30fcu30abu30ebu3067u30b5u30fcu30d0u30fcu306bu4fddu5b58u3055u308cu307eu3059u3002u3053u306eu5f8cu3001u30a4u30f3u30c7u30c3u30afu30b9u5316u30d7u30edu30bbu30b9u304cu59cbu307eu308au3001u30d2u30c7u30aau306fu6307u5b9au3055u308cu305f index_id u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu307eu3059u3002u30a4u30f3u30c7u30c3u30afu30b9u5316u304cu5b8cu4e86u3059u308bu3068u3001video_id u304cu751fu6210u3055u308cu3066u8fd4u3055u308cu3001u305du308cu304cu30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u5206u6790u306bu4f7fu7528u3055u308cu307eu3059u3002
u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u304cu5206u6790u3055u308cu3001u30d2u30c7u30aau7406u89e3u306fu30ecu30a4u30f3u30bau306bu57fau3065u3044u305fu8aacu660eu7684u306au5206u6790u7d50u679cu304cu751fu6210u3055u308cu307eu3059u3002u3053u306eu7d50u679cu306fu3001u53ccu65b9u5411u30b2u30fcu30e0u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu958bu767au3092u6307u5c0eu3059u308bu306eu306bu5f79u7acbu3064u6307u793au3092u63d0u4f9bu3057u307eu3059u3002u5206u6790u30c6u30adu30b9u30c8u306fu3001u30d5u30a9u30fcu30deu30c3u30c8u6307u793au3084u30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u3068u3068u3082u306bu30e2u30fcu30b6u30fcu30d7u30edu30f3u30d7u30c8u306bu542bu305eu308cu307eu3059u3002u3053u306eu30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u306fu3001u751fu6210u3055u308cu308fu305fu51fau529bu304cu5b8cu5168u3067u6a5fu80fdu7684u306au53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3067u3042u308au3001u5206u6790u30c6u30adu30b9u30c8u304bu3089u63a8u5b9au3055u308cu305fu30acu30a4u30c9u30e9u30a4u30f3u3084u6307u793au306bu6e96u62e0u3057u3066u3044u308bu3053u3068u3092u78bau4fddu3057u307eu3059u3002
u305du306eu5f8cu3001SambaNovau3092u901au3058u3066u30b3u30fcu30c9u751fu6210u30d7u30edu30b2u30b9u304cu958bu59cbu3055u308cu3001HTMLu3001CSSu3001u30cau30d0u30b9u30afu30eau30d7u30c8u3092u542bu3080u5358u4e00u306eHTMLu30d5u30a1u30a4u30ebu304cu4f5cu6210u3055u308cu307eu3059u3002u3053u3053u3067u4f7fu7528u3055u308cu308bu30e2u30c7u30ebu306f DeepSeek-V3-0324 u3067u3042u308au3001u9069u5207u306fu30b3u30fcu30c9u3092u751fu6210u3059u308bu524du306bu8003u3048u308bu3053u3068u3067u30d7u30edu30f3u30d7u30c8u3092u51e6u7406u3057u307eu3059u3002u30b3u30fcu30c9u751fu6210u304cu5b8cu4e86u3059u308bu3068u3001u30b9u30c8u30eau30fcu30dfu30f3u30b0u306fu505cu6b62u3057u307eu3059u3002

u30e6u30fcu30c6u30a3u30eau30c6u30a3u95a2u6570 file_service.process_html_content u306fu3001u30ecu30b9u30ddu30f3u30b9u5185u306eHTMLu30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u3057u307eu3059u3002u4f5cu6210u3055u308cu305fHTMLu30d5u30a1u30a4u30ebu306fu3001file_service.save_html_file u3092u4f7fu7528u3057u3066u4fddu5b58u3055u308cu3001u7d71u4e00u3055u308cu305fJSONu69cbu9020u306bu683cu7d0du3055u308cu307eu3059u3002u3053u308cu306bu3088u308au3001u53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u30ecu30f3u30c0u30eau30f3u30b2u3057u3001u751fu6210u3055u308cu305fu30b3u30fcu30c9u3092u8868u793au3059u308bu305fu3081u306eu7d20u65e9u3044u53d6u5f97u304cu53efu80fdu306bu306au308au307eu3059u3002
u8a66u9a13u3092u5bb9u6613u306bu3059u308bu305fu3081u306bu3001u300cu518du751fu6210u300du30dcu30bfu30f3u304cu8a2du3051u3089u308cu3066u3044u307eu3059u3002u3053u308cu306fu3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu30d2u30c7u30aau3092u4f7fu7528u3057u3066u5206u6790u3068u30b3u30fcu30c9u751fu6210u30d7u30edu30b2u30b9u3092u518du5ea6u52d5u304bu3057u3001u540cu3058u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u306bu57fau3065u304fu3055u307eu3056u307eu306au53ccu65b9u5411u6027u306eu53efu80fdu6027u3092u63a2u308bu3053u3068u3092u53efu80fdu306bu3057u307eu3059u3002

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3068u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u306eu5225u306eu65b9u6cd5u306fu3001u500bu4ebau306eTwelveLabs APIu30adu30fcu3092u63a5u7d9au3059u308bu3053u3068u3067u3059u3002APIu30adu30fcu304cu63a5u7d9au3055u308cu308bu3068u3001u5e0cu671bu3059u308b index_id u3068u305du308cu306bu95a2u9023u4ed8u3051u3089u308fu305fu7279u5b9au306eu30d2u30c7u30aau3092u9078u629eu3067u304du307eu3059u3002u30d2u30c7u30aau9078u629eu5f8cu3001u5bfeu5fdcu3059u308b video_id u304cu5206u6790u3092u884cu3044u8aacu660eu30c6u30adu30b9u30c8u3092u751fu6210u3059u308bu305fu3081u306bu4f7fu7528u3055u308cu3001u305du306eu5f8cSambanovau30b2u30fcu30e0u30b3u30fcu30c9u751fu6210u30d4u30d7u30e9u30a4u30f3u3092u901au3055u308cu307eu3059u3002u30d5u30a1u30a4u30ebu51e6u7406u30d7u30edu30b2u30b9u306fu3001HTMLu30d5u30a1u30a4u30ebu3092u62bdu51fau3057u3066u4fddu5b58u3059u308bu305fu3081u306bu3001u524du8ff0u306eu3082u306eu3068u540cu69d8u3067u3059u3002
u81eau8eabu306eu30d2u30c7u30aau3067u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u4f7fu7528u3059u308bu306bu306fu3001u307eu305aTwelveLabs Playgroundu3092u4ecbu3057u3066u30a4u30f3u30c7u30c3u30afu30b9IDu3092u751fu6210u3057u3001u30d2u30c7u30aau3092u30a2u30c3u30d7u30edu30fcu30c9u3057u3066u30a4u30f3u30c7u30c3u30afu30b9u5316u3059u308bu3053u3068u3092u63a8u5968u3057u307eu3059u3002u305du308cu304cu5b8cu4e86u3057u305fu3089u3001u3053u3053u306bAPIu30adu30fcu3092u63a5u7d9au3057u3066u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu6a5fu80fdu3092u5145u5206u306bu6d3bu7528u3057u3066u304fu3060u3055u3044u3002
u6e96u5099u624bu9806
TwelveLabs Playgroundu304bu3089APIu30adu30fcu3092u53d6u5f97u3057u3001u74b0u5883u5909u6570u3092u8a2du5b9au3057u307eu3059u3002
TwelveLabs Playgroundu3092u4ecbu3057u3066pegasus-1.2u3092u9078u629eu3057u3001u30a4u30f3u30c7u30c3u30afu30b9u3092u4f5cu6210u3057u307eu3059u3002u305du3057u3066u3001u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u5c02u7528u306eindex_idu3092u53d6u5f97u3057u307eu3059u3002
GitHubu304bu3089u30d7u30edu30b8u30a7u30afu30c8u3092u30afu30edu30fcu30f3u3057u307eu3059u3002
SambaNovau30c0u30c3u30b7u30e5u30dcu30fcu30c9u304bu3089APIu30adu30fcu3092u53d6u5f97u3057u307eu3059u3002
TwelveLabsu3068SambaNovau306eu8aadu8a3cu60c5u5831u3092u542bu3080.envu30d5u30a1u30a4u30ebu3092u4f5cu6210u3057u307eu3059u3002
u3053u308cu3089u306eu624bu9806u304cu5b8cu4e86u3059u308bu3068u3001u958bu767au3092u59cbu3081u308bu6e96u5099u306eu6574u3044u307eu3059uff01
Video2Gameu30a2u30d7u30eau306eu89e3u8aac
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau306bu5909u63dbu3059u308bu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu69cbu7bc9u65b9u6cd5u306bu7126u70b9u3092u5f53u3066u307eu3059u3002u30a2u30d7u30eau306fu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bNext.jsu3001u30d0u30c3u30afu30a8u30f3u30c3u30c9u306bCORSu3092u6709u52b9u306bu3057u305fFlask APIu3092u4f7fu7528u3057u3066u3044u307eu3059u3002u3053u3053u3067u306fu3001Video2Gameu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4e2du6838u30d0u30c3u30afu30a8u30f3u30c3u30c9u30e6u30fcu30c6u30a3u30eau30c6u30a3u306eu5b9fu88c5u3068u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30bbu30c3u30c8u30a2u30c3u30d7u306bu7126u70b9u3092u5f53u3066u307eu3059u3002
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001SambaNovau3092u4ecbu3057u3066u30a2u30afu30bbu30b9u3059u308bu3053u3068u3067u3001u30b2u30fcu30e0u30b3u30fcu30c9u751fu6210u306bu9ad8u901fu63a8u8ad6LLMu3092u4f7fu7528u3059u308bu65b9u6cd5u306bu7126u70b9u3092u5f53u3066u307eu3059u3002u305du306eu30a2u30afu30bbu30b9u304cu3044u304bu306bu7c21u5358u304bu3092u898bu3066u307fu307eu3057u3083u3046u3002u8a73u7d30u306au30b3u30fcu30c9u69cbu9020u3068u30bbu30c3u30c8u30a2u30c3u30d7u6280u8853u306bu3064u3044u3066u306fu3001GitHubu306e README.md u3092u3054u78bau8a8du304fu3060u3055u3044u3002
1 - u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fTwelveLabsu306eu30d2u30c7u30aau304bu3085u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau3092u751fu6210u3059u308bu65b9u6cd5
1.1 u5fc5u898au306au8a2du5b9au3092u884cu3046
u3059u3079u306eu306eu5fc5u898au306au8a2du5b9au306f config.py u3067u5b9au7fa9u3055u308cu3001u74b0u5883u5909u6570u304bu3089u5024u304cu30edu30fcu30c9u3055u308cu307eu3059u3002u3053u306eu96c6u4e2du5316u3055u308cu305fu8a2du5b9au30a2u30d7u30edu30fcu30c1u306bu3088u308au3001u3059u3079u306eu5909u6570u306bu7c21u5358u306bu30a2u30afu30bbu30b9u3067u304du3001u7d20u6674u3089u3057u304fu6574u7406u3055u308cu7ba1u7406u3057u3084u3059u3044u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu30bbu30c3u30c8u30a2u30c3u30d7u3092u7dadu6301u3067u304du307eu3059u3002
backend/app/config.py (7-24 u884cu76ee)
class Config: ` # API credentials loaded from environment variables TWELVELABS_API_KEY = os.getenv("TWELVELABS_API_KEY") SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY") TWELVELABS_INDEX_ID = os.getenv("TWELVELABS_INDEX_ID") SAMBANOVA_BASE_URL=os.getenv("SAMBANOVA_BASE_URL") APP_URL = os.getenv("APP_URL", "http://localhost:8000") # Directory paths for file organization GAMES_DIR = "generated_games" # Directory to store generated game files CACHE_DIR = "game_cache" # Directory for caching game-related data INSTRUCTIONS_DIR = "instructions" # # Directory containing prompt files # SambaNova service configuration SAMBANOVA_BASE_URL = SAMBANOVA_BASE_URL SAMBANOVA_MODEL = "DeepSeek-V3-0324" # LLM text generation parameters GENERATION_TEMPERATURE = 0.1 GENERATION_TOP_P = 0.1 GENERATION_MAX_TOKENS = 16000 MIN_HTML_LENGTH = 7000
TwelveLabsu3068SambaNovau306eu8aadu8a3cu60c5u5831u3092u8a2du5b9au3057u305fu5f8cu3001INSTRUCTIONS_DIR u304cu521du671fu5316u3055u308cu307eu3059u3002u3053u306eu30c1u30ecu30afu30c8u30eau306bu306fu3001u30d7u30edu30b2u30b9u5168u4f53u3067u4f7fu7528u3055u308cu308bu3059u3079u306eu4e8eu5148u306bu5b9au7fa9u3055u308cu305fu30d7u30edu30f3u30d7u30c8u304cu542bu305eu308cu307eu3059u3002u751fu6210u3055u308cu305fu3059u3079u306eu53ccu65b9u5411u30b2u30fcu30e0u306f GAMES_DIR u306bu4fddu5b58u3055u308cu3001CACHE_DIR u306bu30adu30e3u30c3u30b7u30e5u3055u308cu307eu3059u3002
u30b3u30fcu30c9u751fu6210u306bu4f7fu7528u3055u308cu308bu30e2u30c7u30ebu306f DeepSeek-V3-0324 u3067u3042u308au3001u30e9u30f3u30c0u30e0u6027u3092u6e1bu3089u3059u305fu3081u306b 0.1 u306eu6e29u5ea6u304cu8a2du5b9au3055u308cu3001max_tokens u306eu5236u9650u304cu5b9au7fa9u3055u308cu3066u3044u307eu3059u3002u3057u8a66u3057u3066u307fu305fu3044u5834u5408u306fu3001u3053u308cu3089u306eu30d1u30e9u30e1u30fcu30bfu3092u5a09u66f4u3059u308bu304bu3001u8a2du5b9au5185u3067u5225u306eu30e2u30c7u30ebu306bu5207u308au66ffu3048u308bu3053u306eu304cu3067u304du307eu3059u3002
1.2 u30a4u30f3u30c7u30c3u30afu30b9u3092u53d6u5f97u3059u308b
u30e2u30fcu30b6u30fcu304cu30ddu30fcu30bfu30ebu3092u4ecbu3057u3066TwelveLabs APIu30adu30fcu3092u63a5u7d9au305bu308cu3070u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu305du308cu3092u4f7fu7528u3057u3066u30a2u30abu30a6u30f3u30c8u306bu95a2u9023u4ed8u3051u3089u308fu305fu3059u3079u306eu30a4u30f3u30c7u30c3u30afu30b9u3092u53d6u5f97u3057u307eu3059u3002u305du306eu5f8cu3001u30ecu30b9u30ddu30f3u30b9u304cu69cbu9020u5316u3055u308eu3001u8868u793au3059u308bu305fu3081u306bu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu9001u4fe1u3055u308cu307eu3059u00e3u3002
def get_indexes(self): try: print("Fetching indexes...") # Use direct HTTP request if not self.api_key: print("No API key available") return [] # To get the list of indexes url = "https://api.twelvelabs.io/v1.3/indexes" headers = { "accept": "application/json", "x-api-key": self.api_key } response = requests.get(url, headers=headers) if response.status_code == 200: data = response.json() result = [] # Structuring the relevant information needed for index in data.get('data', []): result.append({ "id": index['_id'], "name": index['index_name'] }) return result else: print(f"Failed to fetch indexes: Status {response.status_code}") return [] except Exception as e: print(f"Error fetching indexes: {e}") return []
1.3 u9078u629eu3055u308cu305f index_id u306bu5bfeu5fdcu3059u308bu30d2u30c7u30aau3092u53d6u5f97u3059u308b
u30e2u30fcu30b6u30fcu304cu30a4u30f3u30c7u30c3u30afu30b9u3092u9078u629eu3059u308bu3068u3001u5bfeu5fdcu3059u308b index_id u304cu30adu30e3u30d7u30c1u30e3u3055u308cu307eu3059u3002u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u751fu6210u3059u308bu306bu306fu3001u305du306eu30a4u30f3u30c7u30c3u30afu30b9u304bu3089u7279u5b9au306eu30d2u30c7u30aau3092u9078u629eu3059u308bu3053u306eu304cu3042u308au307eu3059u3002u9078u629eu3055u308cu305f index_id u3092u4f7fu7528u3057u3066u3001u305du306eu30a4u30f3u30c7u30c3u30afu30b9u306bu95a2u9023u4ed8u3051u3089u308fu305fu3059u3079u306eu30d2u30c7u30aau3092u53d6u5f97u3059u308bu305fu3081u306bu3001u305du306eu30e1u30bdu30c3u30c9u304cu547cu3073u51fau3055u308cu307eu3059u3002
def get_videos(self, index_id): try: # Use direct HTTP request if not self.api_key: print("No API key available") return [] # List of Videos info of that respective index id url = f"https://api.twelvelabs.io/v1.3/indexes/{index_id}/videos" headers = { "accept": "application/json", "x-api-key": self.api_key } response = requests.get(url, headers=headers) if response.status_code == 200: data = response.json() result = [] for video in data.get('data', []): system_metadata = video.get('system_metadata', {}) # Structuring the response to get relevant information to showcase on the frontend result.append({ "id": video['_id'], "name": system_metadata.get('filename', f'Video {video["_id"]}'), "duration": system_metadata.get('duration', 0) }) return result else: print(f"Failed to fetch videos: Status {response.status_code}") return [] except Exception as e: print(f"Error fetching videos for index {index_id}: {e}") return []
u30d2u30c7u30aau3092u9078u629eu3059u308bu3068u3001video_id u304fu305du306eu30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u306eu305du306eu5f8cu306eu5206u6790u30d7u30edu30b2u30b9u306bu9001u4fe1u3055u308cu307eu3059u3002
1.4 pegasus-1.2 u3067u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u5206u6790u3059u308b
u30a2u30cau30e9u30a4u30bau30e6u30fcu30c6u30a3u30eau30c6u30a3u306eu76eeu7684u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u3057u3001u305du306eu30b3u30f3u30c6u30adu30b9u30c8u306bu57fau3065u3044u3066u6709u610fu7fa9u306eu3042u308bu6307u793au3092u751fu6210u3059u308bu3053u306eu3067u3059u3002u3053u308cu3089u306eu6307u793au306fu3001u53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u69cbu7bc9u3059u308bu305fu3081u306eu57fau790eu3068u306au308au3001u305du306eu5f8cu306eu30b3u30fcu30c9u751fu6210u30d7u30edu30b2u30b9u3092u5c0eu304du307eu200bu200bu3059u3002u3053u306eu5206u6790u306bu4f7fu7528u3055u308cu308bu30d7u30edu30f3u30d7u30c8u306fu3001u30d0u30c3u30afu30a8u30f3u30c3u30c9u3067u30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u3068u3057u3066u4e8eu514au306bu5b9au7fa9u3055u308cu3066u3044u307eu3059u3002u3053u3061u3089u3067u3001u5206u6790u30d7u30edu30f3u30d7u30c8 u304cu78bau8a8du3067u304eu307eu3059u3002
def analyze_video(self, video_id, prompt): try: # Send video analysis request to TwelveLabs API with custom prompt analysis_response = self.client.analyze( video_id=video_id, prompt=prompt ) return analysis_response.data except Exception as e: print(f"Error analyzing video {video_id}: {e}") raise e
video_id u3068u30d7u30edu30f3u30d7u30c8u306fu3001self.client.analyze u306bu30d1u30e9u30e1u30fcu30bfu3068u3057u3066u63d0u4f9bu3055u308cu3001u305du306eu30e1u30bdu30c3u30c9u304cu30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u30fbu5206u6790u3057u3066u6307u793au7d50u679cu3092u751fu6210u3057u307eu3059u3002
1.5 SambaNova u3092u4f7fu7528u3057u305fu53ccu65b9u5411u30b2u30fcu30e0u30b3u30fcu30c9u306eu751fu6210
u5206u6790u7d50u679cu3092u53d7u3051u53d6u308bu306fu3058u3081u308bu3068u3001u751fu6210u3055u308cu305fu30b3u30fcu30c9u30e6u30fcu30c6u30a3u30eau30c6u30a3u304cu200bu200bu30c8u30eau30acu30fcu3055u308cu307eu3059u3002u3053u306eu624bu9806u3067u306fu3001u514au306bu5b9au7fa9u3055u308cu305fu30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u3068u3068u3082u306bu3001u5206u6790u51fau529bu304cu30e2u30fcu30b6u30fcu30d7u30edu30f3u30d7u30c8u3068u3057u3066u9001u3089u308cu307eu3059u3002u4f7fu7528u3055u308cu308bu30e2u30c7u30eb DeepSeek-V3-0324 u306fu3001u524du8ff0u306eu624bu98061.1u3067u8a2du5b9au3057u305fu3082u306eu3068u540cu3058u3067u3001u3059u3002
u3053u306e u30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8 u306fu3001u51fau529bu306eu4e2du6838u306eu8981u4ef6u3068u671fu5f85u3055u308cu308bu69cbu9020u3092u69cbu60f3u3057u3001u30e2u30c7u30ebu304cu30bfu30b9u30afu306eu76eeu7684u3068u5236u7d04u3092u7406u89e3u3057u3066u3044u308bu3053u306eu3092u78bau4fddu3057u307eu3059u3002u4e00u65b9u3067u3001u30e2u30fcu30b6u30fcu30d7u30edu30f3u30d7u30c8 u306fu3001u5206u6790u7d50u679cu306bu52a0u3048u3001u30ecu30a4u30a2u30a6u30c8u3001u30c7u30b6u30a4u30f3u3001u914du8272u3001u30d5u30a9u30fcu30deu30c3u30c8u306bu95a2u3059u308bu8a73u7d30u306au8ffdu52a0u6307u793au3092u7d44u307fu8fbcu3093u3067u3044u307eu3059u3002u3053u308cu3089u306eu30d7u30edu30f3u30d7u30c8u304cu5fc5u898au306bu5fdcu3058u3066u3001u30e2u30c7u30ebu3092u30acu30a4u30c9u3057u3066u3001u7126u70b9u304cu7d5eu3089u308cu305fu6574u7406u3055u308cu305fu53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u751fu6210u3057u307eu3059u3002
def generate_game_stream(self, system_prompt, user_prompt): print("Starting streaming generation...") if not self._test_api_connection(): yield "Error: Sambanova API is not reachable" return try: start_time = time.time() response = self.client.chat.completions.create( model=current_app.config['SAMBANOVA_MODEL'], messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt} ], temperature=current_app.config['GENERATION_TEMPERATURE'], top_p=current_app.config['GENERATION_TOP_P'], max_tokens=current_app.config['GENERATION_MAX_TOKENS'], stream=True ) print(f"API call initiated in {time.time() - start_time:.2f}s") chunk_count = 0 total_content = "" last_chunk_time = time.time() for chunk in response: current_time = time.time() if current_time - last_chunk_time > 30: # 30 second timeout print(f"No chunk received for 30 seconds, breaking...") break delta = getattr(chunk.choices[0], 'delta', None) content = getattr(delta, 'content', '') if delta else '' if content: chunk_count += 1 total_content += content last_chunk_time = current_time # Print live streaming progress if chunk_count % 20 == 0: # Print every 20 chunks print(f"Stream: {chunk_count} chunks, {len(total_content)} chars") yield content print(f"Streaming completed: {chunk_count} chunks, {len(total_content)} total chars") print(f"Total streaming time: {time.time() - start_time:.2f}s") except Exception as e: error_msg = f"Streaming error: {str(e)}" print(error_msg) print(f"Error type: {type(e).__name__}") if hasattr(e, 'response'): print(f"Response status: {e.response.status_code}") print(f"Response text: {e.response.text}") yield error_msg
SambaNova u306e API u3092 stream=True u3067u547cu3073u51fau3059u3068u3001u751fu6210u3055u308cu305fu30b3u30f3u30c6u30f3u30c4u306fu4f5cu6210 u3055u308cu305fu9806u306bu5206u5272u3055u308cu3066u9001u308au8fd4u3055u308cu3001u3053u306eu95a2u6570u304cu305du308cu3092u3059u3050u306bu30e2u30fcu30b6u30fcu306bu8ff4u3057u307eu3059u3002u898bu4e8bu306au306eu306fu3001u5185u8535u3055u308cu305fu5b89u5168u5b9au4fddu6a5fu69cbu3067u3059u3002u30deu30c3u30c1u30f3u30b0u306eu7121u99c4u306au547cu3073u51fau3059u3092u907fu3051u308bu305fu3081u306bu3001u307eu305a API u63a5u7d9au3092u30c6u30b9u30c8u3057u3001u8a70u307eu3063u305fu63a5u7d9au3092u635eu3046u305fu3081u306b 30 u79d2u306eu30bfu30a4u30e0u30a2u30a6u30c8u3092u5b9fu88c5u3057u300120 u30c1u30e3u30f3u30afu3054u3068u306bu8a73u7d30u306au30e1u30c8u30eau30afu30b9u3092u8a18u9332u3059u308bu305fu3081u3001u30d1u30d5u30a9u30fcu30deu30f3u30b9u3092u30eau30a2u30ebu30bfu30a4u30e0u3067u76e3u8996u3067u3042u308au307eu3059u00e3u3002
1.6 u751fu6210u306eu305fu3081u306eu95a2u6570u547cu3073u51fau3057u30d4u30d7u30e9u30a4u30f3
u3053u306eu30bbu30afu30b7u30e7u30f3u3067u306fu3001u524du8ff0u306eu30e2u30fcu30c6u30a3u30eau30c6u30a3u95a2u6570u304cu547cu3073u51fau3055u308cu5b9fu884cu3055u308cu308bu3001u30d7u30edu30b2u30b9u306eu5168u4f53u30d4u30d7u30e9u30a4u30f3u306bu3064u3044u3066u8aacu660eu3057u307eu3059u3002u3053u308cu306fu3001u5206u6790u306bu5fc5u898au306a video_id u3068u95a2u9023u4ed8u3051u3089u308fu305f API u30adu30fcu306eu5b58u5728u3092u691cu8a3cu3059u308bu3053u306eu304bu3089u59cbu307eu308au307eu3059u3002u78bau8a8du3055u308cu308bu306fu3058u3081u308bu3068u3001u5206u6790u30d7u30edu30f3u30d7u30c8u304fu304cu30ddu30fcu30c9u3055u308cu3001analyze_video u30aau30fcu30c6u30a3u30eau30c6u30a3u304cu30aau30eau30acu30fcu3055u308cu3066u6307u793au7d50u679cu3092u751fu6210u3057u307eu3059u3002u305du306eu5f8cu3001SambaNova u30b7u30b9u30c6u30e0 u30d7u30edu30f3u30d7u30c8u304cu30ddu30fcu30c9u3055u308cu3001u30b3u30fcu30c9u751fu6210 u30d7u30edu30b2u30b9u3092 u958bu59cbu3059u308bu30bfu30e1u306bu4f7fu7528u3055u308cu307eu3059u3002SambaNova u304bu3089u306eu7d50u679cu306fu30c1u30e3u30f3u30afu3054u3068u306bu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu30b9u30c8u30eau30fcu30dfu30f3u30b0u3055u308cu3001u30e2u30fcu30b6u30fcu306fu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30e9u30a4u30d6u751fu6210u3092u898bu308bu3053u306eu304cu3067u304du307eu3059u3002
u751fu6210u304fu5b8cu4e86u3057u30b9u30c8u30eau30fcu30dfu30f3u30b0 u304cu7d42u308fu308bu3068u3001u30e6u30fcu30c6u30a3u30eau30c6u30a3 u95a2u6570 file_service.process_html_content u304cu30ecu30b9u30ddu30f3u30b9u304bu3089 HTML u30b3u30f3u30c6u30f3u30c4 u3092u62bdu51fau3057u307eu3059u3002u3053u306eu62bdu51fau3055u308cu305f HTML u306fu3001file_service.save_html_file u3092u4f7fu7528u3057u3066u5225u30d5u30a1u30a4u30ebu3068u3057u3066u4fddu5b58u3055u308cu307eu3059u3002u4fddu5b58u3055u308cu305f HTML u30d1u30b9u3068u3068u3082u306bu3001video_idu3001video_analysisu3001u304au3088u3073u95a2u9023u3059u308bu30e1u30bf u30c7u30fcu30bfu306au3069u306eu4ed6u306eu95a2u9023u3059u308bu8a73u7d30u306fu3001u5f8cu3067u7c21u5358u306bu53d6u5f97 u3067u304du308bu3088u3046u306bu7d71u4e00u3055u308cu305f JSON u30d5u30a1u30a4u30ebu306b u683cu7d0du3055u308cu307eu3059u3002
@api_bp.route('/twelvelabs/regenerate', methods=['POST', 'GET']) @handle_errors def twelvelabs_regenerate(): from app.services.sample_games_service import SampleGamesService from app.services.twelvelabs_service import TwelveLabsService from app.services.sambanova_service import SambanovaService from app.services.file_service import FileService def event_stream(video_id, api_key): # Initialize service for managing generated games, consisting the loading the file handling sample_games_service = SampleGamesService() # Validate required parameters before processing if not video_id: yield f"event: error\ndata: video_id is required\n\n" return if not api_key: yield f"event: error\ndata: API key is required\n\n" return try: # Step 1 - Analyze video content using TwelveLabs yield f"event: progress\ndata: Starting analysis with TwelveLabs...\n\n" # Initialize TwelveLabs service with provided API key twelvelabs_service = TwelveLabsService(api_key=api_key) # Get analysis prompt template and analyze the video analysis_prompt = current_app.prompt_service.get_prompt('analysis') video_analysis = twelvelabs_service.analyze_video(video_id, analysis_prompt) yield f"event: analysis\ndata: {video_analysis}\n\n" # Step 2 - Generate game code using SambaNova AI yield f"event: progress\ndata: Generating game with SambaNova...\n\n" sambanova_service = SambanovaService() # Prepare prompts for game generation using video analysis game_generation_prompt = current_app.prompt_service.get_prompt('game_generation', video_analysis=video_analysis) system_prompt = current_app.prompt_service.get_prompt('system') try: # Stream game generation in real-time chunks streamed_html = "" # Process each chunk of generated content as it arrives for chunk in sambanova_service.generate_game_stream(system_prompt, game_generation_prompt): if chunk: streamed_html += chunk # Send each chunk to client for real-time display yield f"event: game_chunk\ndata: {chunk}\n\n" # Step 3 - Save and process the complete generated game if streamed_html: # Process and clean up the generated HTML content file_service = FileService() html_content = file_service.process_html_content(streamed_html) # Save HTML file to disk with video ID as identifier html_file_path = file_service.save_html_file(html_content, video_id) # Create game metadata and save to file storage game_data = sample_games_service.create_game_data( video_id, video_analysis, html_file_path, twelvelabs_video_ids=[video_id], youtube_url='', video_title=f'TwelveLabs Video {video_id}', channel_name='TwelveLabs', view_count='Generated' ) sample_games_service.save_game(game_data) else: # No content was generated - report error to client yield f"event: error\ndata: No game content was generated\n\n" return except Exception as e: print(f"Error in SambaNova streaming: {str(e)}") yield f"event: error\ndata: Error streaming from SambaNova: {str(e)}\n\n" return yield f"event: done\ndata: [DONE]\n\n" except Exception as e: print(f"Error in TwelveLabs processing: {str(e)}") yield f"event: error\ndata: Error processing TwelveLabs video: {str(e)}\n\n" # Handle different HTTP methods for parameter extraction if request.method == 'GET': video_id = request.args.get('video_id') api_key = request.args.get('api_key') else: data = request.get_json() video_id = data.get('video_id') api_key = request.headers.get('X-Twelvelabs-Api-Key') if not video_id: return jsonify({"error": "video_id is required"}), 400 return Response(stream_with_context(event_stream(video_id, api_key)), mimetype='text/event-stream')
u751fu6210u30d7u30edu30b2u30b9 u304cu5b8cu4e86u3057 u30c1u30a7u30f3u30afu51e6u7406u304c u305du308cu305eu308cu7d42u308fu308bu3068u3001u751fu6210u3055u308cu305fu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3 u3068u305du306e u30b3u30fcu30c9u306f u4fddu5b58u3055u308cu305f JSON u304bu3089 u30edu30fcu30c9u3055u308cu3001u30ddu30fcu30bfu30eb u4e0au306bu30ecu30f3u30c0u30eau30f3u30b0u3055u308cu307eu3059u3002
2 - YouTubeURLu3092u4ecbu3057u3066u751fu6210u3059u308bu30bfu30e1u306eu95a2u6570u547cu3073u51fau3057u30d4u30d7u30e9u30a4u30f3
u30a4u30f3u30bfu30e9u30afu30c6u30a3u30d6u306au5b66u7fd2u30a2u30d7u30eau3092u751fu6210u3059u308bu30bfu30e1u306b YouTube u306e URL u3092u4f7fu7528u3059u308bu3084u3046u306au4ee3u66ffu624bu6bb5u3067u3082u3001u5168u4f53u306eu30d4u30d7u30e9u30a4u30f3u306fu307bu3068u3093u3069u540cu3058u3067u3059u3002u4e3bu306au9055u3044u306fu521du671fu306eu624bu9806u306bu3042u308au307eu3059u3002u30d2u30c7u30aau306fu307eu305a u51e6u7406u3055u308c u30edu30fcu30abu30eb u307eu305fu306f u30b5u30fcu30d0u30fc u306b u4fddu5b58u3055u308cu3001u305du306eu5f8c TwelveLabs API u3092u4f7fu7528u3057u3066 u30a4u30f3u30c7u30c3u30afu30b9u5316 u3055u308cu307eu3059u3002u30b5u30ddu30fcu30c8u3055u308cu3066u3044u308b u30d7u30e9u30c3u30c8u30d5u30a9u30fcu30e0 URL u304bu3089 u30d2u30c7u30aau306e u30c0u30a6u30f3u30edu30fcu30c9u3092 u51e6u7406u3059u308b u30e6u30fcu30c6u30a3u30eau30c6u30a3u3092 u7d44u307fu8fbcu3080 u3053u306eu304fu3001u305du306eu5f8c u30a4u30f3u30c7u30c3u30afu30b9u5316u306e u5fc5u898au306a u624bu9806 u304cu8a2du5b9au3055u308b u3053u306eu304cu3042u308au307eu3059u3002
u30a4u30f3u30c7u30c3u30afu30b9u5316u304cu3069u306eu3088u3046u306bu884cu308fu308cu308bu304bu3092u7406u89e3u3059u308bu306bu306fu3001u4ee5u4e0bu306eu30b3u30fcu30c9u30b9u30cbu30c3u30dau30c3u30c8u3092u53c2u7167u3057u3066u304fu3060u3055u3044u3002
def _index_video_file(self, file_path, index_id): try: # Create a new indexing task for the video file task = self.twelvelabs_service.client.task.create( index_id=index_id, file=file_path, ) print(f"Indexing task created: {task.id}") max_wait_time = 900 start_time = time.time() while time.time() - start_time < max_wait_time: task = self.twelvelabs_service.client.task.retrieve(task.id) # Handle different task status outcomes if task.status == "ready": print(f"Indexing completed successfully. Video ID: {task.video_id}") # Indexing completed successfully - video is now searchable/analyzable return task.video_id elif task.status == "failed": print(f"Indexing failed: {task.status}") return None elif task.status in ["processing", "pending"]: elapsed = int(time.time() - start_time) print(f"Indexing in progress... Status: {task.status} (Elapsed: {elapsed}s)") time.sleep(15) else: print(f"Unknown status: {task.status}") time.sleep(10) print("Indexing timed out") return None except Exception as e: print(f"Error during video indexing: {str(e)}") return None
YouTube URL u304bu3089 u53ccu65b9u5411u30a2u30d7u30ea u751fu6210u307eu3067u306e u5b8cu5168u306a u30d7u30edu30b2u30b9 u30d4u30d7u30e9u30a4u30f3u306fu3001u3053u3061u3089u3067 u78bau8a8du3067u304du307eu3059u3002
YouTube URL u30d2u30c7u30aa u5411u3051u306e u518du751fu6210 u6a5fu80fdu306fu3001u30d2u30c7u30aau304c u3059u3067u306b u30a4u30f3u30c7u30c3u30afu30b9u5316 u3055u308cu3001u518du5206u6790 u3084 u518du751fu6210 u306e u6e96u5099u304c u6574u3063u3066u3044u308b u305fu3081u3001u524du8ff0u306e u3082u306eu3068 u5168u304f u540cu3058 u3088u3046u306b u52d5u4f5cu3057u307eu3059u3002
u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u306eu89e3u8aac u3092 u6df1u3081u308b u306eu306b u5f79u7acbu3061u3001u30d2u30c7u30aau3092 u4f53u9a13 u3057 u30a4u30f3u30bfu30e9u30afu30c8 u3057 u5b66u3073 u904au3076u3001 u307eu3063u305fu304f u65b0u3057u3044 u65b9u6cd5 u3092 u63d0u4f9bu3059u308b u30ddu30fcu30c3u30eb u306e u6a5fu80fdu3092 u30b9u30b0 u306b u78bau8a8du3057u307eu3057u3087u3046u3002

u30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u8a66u3059u30bfu30e1u306e u3055u3089u306au308b u30a2u30a4u30c7u30a2
u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u304cu3069u306eu3088u3046u306b u53ccu65b9u5411u306e u4f53u9a13u306b u5909u308fu308bu304b u3092u7406u89e3u3059u308b u3053u306eu306fu3001u3088u308a u9b45u529bu7684u306eu3001 u305du3057u3066 u5fc5u898au306bu5fdcu3058u305f u5b66u7fd2u306e u9053u3092 u958bu304du307eu3059u3002u30a2u30cau30e9u30a4u30ba u30a8u30f3u30b8u30f3 u3068 Sambanova u3092 u4f7fu3063u3066 u8a66u3059u3053u306eu304cu3067u304du308b u5b9fu9a13u7684u306a u65b9u5411 u306fu3001u4ee5u4e0bu306eu901au308a u3067u3059uff1a
ud83cudfae u30d5u30a3u30fcu30c9u30d0u30c3u30af u30ebu30fcu30d7 u306bu3088u308b u9ad8u901fu306a u30a4u30c6u30ecu30fcu30b7u30e7u30f3 u2014 SambaNovau3092 u6d3bu7528u3057u305f u30b2u30fcu30e0u30b3u30fcu30c9u751fu6210u30ebu30fcu30d7u306bu3001u30e2u30fcu30b6u30fc u30d5u30a3u30fcu30c9u30d0u30c3u30af u3092 u76f4u63a5 u7d44u307fu8fbcu307fu307eu3059u3002 u3000
ud83dudd0d u6df1u3044 u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u306e u7814u7a76 u2014 u9ad8u901fu63a8u8ad6u30e2u30c7u30ebu3092 u4f7fu3063u3066 u30d2u30c7u30aa u5206u6790 u306e u8a73u7d30u306a u89e3u8aac u3092u884cu3044u307eu3059u3002u4e3bu306a u610fu898b u3092 u81eau52d5u7684u306b u62bdu51fau3057u3001u53c2u7167 u3092 u7279u5b9au3057u3001u95a2u9023u3059u308b u5f15u7528 u3084 u5916u90e8u306e u5b66u7fd2u8cc7u6599 u3092 u660eu3089u304bu306b u3057u307eu3059u3002
ud83eudde0 u30d2u30c7u30aa Agentic AI u2014 u30a8u30fcu30b8u30a7u30f3u30c8u30d4u30d7u30e9u30a4u30f3 u306e u4e00u90e8u3068u3057u3066 u63a8u8ad6u30d9u30fcu30b9 u306e u63a8u8ad6u30e2u30c7u30ebu3092 u7d45u5408 u3057u307eu3059u3002u3053u308cu306bu3088u308au3001 u30b7u30b9u30c6u30e0 u306fu30d2u30c7u30aau7de8u96c6u306e u5909u63db u306bu5fc5u898au306a u8a08u753b u3092 u7acbu3066u3001u8abfu6574u3057u3001 u9069u5207u306a u30c4u30fcu30eb u3092 u4f7fu3046 u3053u306eu304cu3067u304du307eu3059u3002
u304au308fu308au306b
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu306fu3001u30d2u30c7u30aau7406u89e3u304cu3001 u79c1u305fu3061 u304cu5b66u3073 u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u3068 u30a4u30f3u30bfu30e9u30afu30c8 u3059u308b u65b9u6cd5 u3092u3001 u3069u306eu3088u3046u306b u518du5b9au7fa9 u3067u304du308b u304bu3092 u63a2u308a u307eu3059u3002 u30d2u30c7u30aa u5206u6790 u751fu6210u306e u305fu3081u306b TwelveLabs u3092u3001u305du3057u3066 u9ad8u301fu306a u30b3u30fcu30c9u30d9u30fcu30b9 u30b2u30fcu30e0 u751fu6210 u306e u305fu3081u306b SambaNova u3092 u7d44u307fu5408u308fu305bu308b u3053u306eu3067u3001 u53d7u52d5u7684u306e u6559u80b2u30d2u30c7u30aau3092 u53ccu65b9u5411u306e u30b2u30fcu30e0u578b u5b66u7fd2 u4f53u9a13 u306b u5909u3048u308b u30b7u30b9u30c6u30e0 u3092 u69cbu7bc9 u3057u307eu3057u305fu3002Video2Game u306fu3001 u30deu30ebu30c1u30e2u30fcu30c0u30ebu89e3 u3068u3001 u904au3073 u5fc3 u306e u3042u308b u5b66u3073u3001u30e0 u3092 u7d39u4ecbu3057 u53ccu65b9u306e u67b6u3051u6a4b u3068u306au308bu3053u3068u3067u3001 u5f93u6765u306e u30d2u30c7u30aa u518du751f u3092 u8d85u3048u305f u6c89u6d78 u578b u306e u500bu4ebau5316 u3055u308cu305f u6559u80b2 u3092u63d0u4f9bu3057u307eu3059u3002
u8ffdu52a0u306eu30eau30bdu30fcu30b9
u30d2u30c7u30aa u5206u6790 u30a8u30f3u30b8u30f3 Pegasus-1.2 u306bu3064u3044u3066u3001 u3088u308a u8a73u3057u304f u5b66u3073 u307eu3057u3087u3046u3002TwelveLabs u3092 u3055u3089u306b u63a2u308au3001 u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4 u5206u6790 u306e u7406u89e3u3092 u6df1u3081u308b u30bfu30e1u306bu3001 u3053u308cu3089u306e u30c4u30fcu30eb u3092 u78bau8a8d u3057u3066 u304fu3060u3055u3044uff1a
u3055u3089u306au308b u30e6u30fcu30b9 u30b1u30fcu30b9 u306e u63a2u7d22uff1a SambaNova u30e2u30c7u30eb u30cfu30d6u3092 u8a2au308cu3066u3001 u3055u307eu3056u307eu306a u30e2u30c7u30eb u3068 u30d3u30b8u30cdu30b9 u306e u5ea7u6a19 u306b u5408u308fu305bu305f u985eu4f3cu306e u30efu30fcu30afu30d5u30edu30fcu3092 u3069u306eu3088u3046u306b u5b9fu88c5 u3059u308b u304b u3092 u5b66u3092u307fu3001u63a2u3063u3066u307f u307eu3057u3087u3046u3002
u8a71u3057 u5408u3044u306b u53c2u52a0u3059u308buff1a u3053u306e u7d45u5408 u306b u5c0du3059u308b u30d5u30a3u30fcu30c9u30d0u30c3u30af u3092 TwelveLabs Discordu3067 u5171u6709u3057 u307eu3057u3087u3046u3002
u30c1u30e5u30fcu30c8u30eau30a2u30eb u3092 u63a2u308buff1a u5b8cu5168u306a u30c1u30e5u30fcu30c8u30eau30a2u30eb u3067u3001 TwelveLabs u306e u529b u3092 u3055u3089u306b u6df1u304f u5b66u3073 u307eu3057u3087u3046u3002
u3053u308cu3089u306e u30eau30bdu30fcu30b9 u3092 u4f7fu3063u3066 u77e5u8b5a u3092 u3072u308du3052u3001 TwelveLabs u306e u30d2u30c7u30aau7406u89e3u6280u8853 u3092 u4f7fu3063u305f u9769u65b0u306e u30a2u30d7u30ea u3092 u4f5cu308b u3053u306eu3092 u5fdcu63f4u3057 u307eu3059u3002
u306fu3058u3081u306b
u6559u80b2u30d2u30c7u30aau304cu5358u306bu898bu305bu3066u4f1du3048u308bu3060u3051u3067u306fu306au304fu3001u305du308cu4ee5u4e0au306eu3053u3068u304cu3067u304du308bu3068u3057u305fu3089u3069u3046u3067u3057u3087u3046uff1f ud83cudfae
u53d7u52d5u7684u306au30d2u30c7u30aau8b1bu7fa9u3092u3001u53d7u8b1bu751fu304cu5358u306bu8996u8074u3059u308bu306eu3067u306fu306au304fu3001u30b3u30f3u30bbu30d7u30c8u3092u30d7u30ecu30a4u3057u306au304cu3089u5b66u3076u3001u53ccu65b9u5411u306eu30deu30fcu30e0u30d9u30fcu30b9u306eu5b66u7fd2u4f53u9a13u306bu5909u3048u308bu3053u3068u3092u60f3u50cfu3057u3066u307fu3066u304fu3060u3055u3044u3002
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001TwelveLabsu3092u6d3bu7528u3057u3066u3001YouTubeu306eu6559u80b2u30d2u30c7u30aau3092u9b45u529bu7684u306au5b66u7fd2u30deu30fcu30e0u306bu5909u63dbu3059u308bu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u69cbu7bc9u3057u307eu3059u3002TwelveLabsu30a2u30cau30e9u30a4u30bau30a8u30f3u30b8u30f3u3068u3001SambaNovau306eu63a8u8ad6u30e2u30c7u30ebu3092u7d44u307fu5408u308fu305bu308bu3053u3068u3067u3001u30d2u30c7u30aau304bu3089u6709u610fu7fa9u306au30b3u30f3u30c6u30f3u30c4u3092u62bdu51fau3057u3001u305du308cu3092u53ccu65b9u5411u306eu5b66u7fd2u30e2u30b8u30e5u30fcu30ebu306bu5909u63dbu3059u308bu3053u3068u304cu3067u304du307eu3059u3002
Video2Gameu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u304cu3069u306eu3088u3046u306bu52d5u4f5cu3059u308bu306eu304bu3001u305du3057u3066TwelveLabs Python SDKu3068SambaNovau3092u4f7fu7528u3057u3066u3001u30d2u30c7u30aau7406u89e3u3068u9ad8u901fu63a8u8ad6LLMu3092u7528u3044u305fu540cu69d8u306eu30bdu30eau30e5u30fcu30b7u30e7u30f3u3092u3069u306eu3088u3046u306bu69cbu7bc9u3067u304du308bu304bu3092u63a2u3063u3066u307fu307eu3057u3083u3046u3002
u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30c7u30e2u306fu3053u3061u3089u3067u4f53u9a13u3067u304du307eu3059uff1aVideo2Gameu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3
u524du63d0u6761u4ef6
TwelveLabs Playgroundu306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3066u3001APIu30adu30fcu3092u767au884cu3057u307eu3059u3002
SambaNovau306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3001u30e2u30c7u30ebu306bu30a2u30afu30bbu30b9u3059u308bu305fu3081u306eAPIu30adu30fcu3092u767au884cu3057u307eu3059u3002
u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30eau30ddu30b8u30c8u30eau306fu3001GitHubu30eau30ddu30b8u30c8u30eau3067u78bau8a8du3067u304du307eu3059u3002
Pythonu3001Flasku3001u304au3088u3073Next.jsu306bu7cbeu901au3057u3066u3044u308bu3053u306eu304cu671bu307eu3057u3044u3067u3059u3002
u30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3
u3053u306eu30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u5206u6790u3059u308bu3053u3068u3067u30d2u30c7u30aau7406u89e3u3092u793au3057u3001u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4f5cu6210u3092u652fu63b4u3057u307eu3059u3002u3053u308cu306fu3001u9ad8u901fu63a8u8ad6LLMu306eu30b3u30fcu30c9u751fu6210u306bu3088u3063u3067u884cu308fu308cu307eu3059u3002u30e2u30fcu30b6u30fcu306fu3001TwelveLabsu306eAPIu30adu30fcu3092u63a5u7d9au3059u308bu3053u3068u3067u3001u30d2u30c7u30aau306eURLu3092u63d0u4f9bu3059u308bu304bu3001u307eu305fu306fu3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu30d2u30c7u30aau304bu3089u76f4u63a5u30d2u30c7u30aau3092u9078u629eu3067u304du307eu3059u3002
u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu76eeu7684u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u304bu3089u306eu53ceu30bcu3068u53ccu65b9u5411u6027u3092u5099u3048u305fu65b0u3057u3044u5b66u7fd2u4f53u9a13u3092u63d0u4f9bu3059u308bu3053u3068u3067u3059u3002u3053u3061u3089u3067u3001u30b3u30fcu30c9u306eu8a73u7d30u306au8aacu660eu3068u30c7u30e2u3092u3054u89a7u3044u305fu3060u3051u307eu3059 u2014

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4ed5u7d44u307f
u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f2u3064u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u30e2u30fcu30c9u3092u30b5u30ddu30fcu30c8u3057u3066u3044u307eu3059 u2014
YouTubeu52d5u753bURLu3092u4f7fu7528u3059u308bu5834u5408uff1aYouTubeu52d5u753bu306eURLu3092u63d0u4f9bu3059u308bu3068u3001u30b7u30b9u30c6u30e0u304cu52d5u753bu3092u51e6u7406u30fbu5206u6790u3057u3001SambaNovau3092u4f7fu7528u3057u305fu9ad8u901fu63a8u8ad6LLMu30e2u30c7u30ebu306bu3088u3063u3066u3001u52d5u753bu306bu57fau3065u304fu53ccu65b9u5411u306eu30b2u30fcu30e0u578bu5b66u7fd2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u81eau52d5u751fu6210u3057u307eu3059u3002
TwelveLabs APIu30adu30fcu3092u4f7fu7528u3059u308bu5834u5408uff1au500bu4ebau306eTwelveLabs APIu30adu30fcu3092u63a5u7d9au3057u3066u3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu306fu3058u3081u3066u3044u308bu81eau8eabu306eu52d5u753bu306bu30a2u30afu30bbu30b9u3057u3001u64cdu4f5cu3057u307eu3059u3002u63a5u7d9au3059u308bu3068u3001u65e2u5b58u306eu30a4u30f3u30c7u30c3u30afu30b9IDu3068u5bfeu5fdcu3059u308bu52d5u753bu3092u9078u629eu3067u304du3001u30b7u30b9u30c6u30e0u306fu9078u629eu3055u308cu305fu52d5u753bu30b3u30f3u200bu200bu30c6u30f3u30c4u306bu57fau3065u304fu53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u751fu6210u3057u307eu3059u3002
YouTubeu306eURLu304cu63d0u4f9bu3055u308cu308bu3068u3001u30d2u30c7u30aau306fu307eu305au51e6u7406u3055u308cu3001u30edu30fcu30abu30ebu3067u30b5u30fcu30d0u30fcu306bu4fddu5b58u3055u308cu307eu3059u3002u3053u306eu5f8cu3001u30a4u30f3u30c7u30c3u30afu30b9u5316u30d7u30edu30bbu30b9u304cu59cbu307eu308au3001u30d2u30c7u30aau306fu6307u5b9au3055u308cu305f index_id u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu307eu3059u3002u30a4u30f3u30c7u30c3u30afu30b9u5316u304cu5b8cu4e86u3059u308bu3068u3001video_id u304cu751fu6210u3055u308cu3066u8fd4u3055u308cu3001u305du308cu304cu30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u5206u6790u306bu4f7fu7528u3055u308cu307eu3059u3002
u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u304cu5206u6790u3055u308cu3001u30d2u30c7u30aau7406u89e3u306fu30ecu30a4u30f3u30bau306bu57fau3065u3044u305fu8aacu660eu7684u306au5206u6790u7d50u679cu304cu751fu6210u3055u308cu307eu3059u3002u3053u306eu7d50u679cu306fu3001u53ccu65b9u5411u30b2u30fcu30e0u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu958bu767au3092u6307u5c0eu3059u308bu306eu306bu5f79u7acbu3064u6307u793au3092u63d0u4f9bu3057u307eu3059u3002u5206u6790u30c6u30adu30b9u30c8u306fu3001u30d5u30a9u30fcu30deu30c3u30c8u6307u793au3084u30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u3068u3068u3082u306bu30e2u30fcu30b6u30fcu30d7u30edu30f3u30d7u30c8u306bu542bu305eu308cu307eu3059u3002u3053u306eu30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u306fu3001u751fu6210u3055u308cu308fu305fu51fau529bu304cu5b8cu5168u3067u6a5fu80fdu7684u306au53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3067u3042u308au3001u5206u6790u30c6u30adu30b9u30c8u304bu3089u63a8u5b9au3055u308cu305fu30acu30a4u30c9u30e9u30a4u30f3u3084u6307u793au306bu6e96u62e0u3057u3066u3044u308bu3053u3068u3092u78bau4fddu3057u307eu3059u3002
u305du306eu5f8cu3001SambaNovau3092u901au3058u3066u30b3u30fcu30c9u751fu6210u30d7u30edu30b2u30b9u304cu958bu59cbu3055u308cu3001HTMLu3001CSSu3001u30cau30d0u30b9u30afu30eau30d7u30c8u3092u542bu3080u5358u4e00u306eHTMLu30d5u30a1u30a4u30ebu304cu4f5cu6210u3055u308cu307eu3059u3002u3053u3053u3067u4f7fu7528u3055u308cu308bu30e2u30c7u30ebu306f DeepSeek-V3-0324 u3067u3042u308au3001u9069u5207u306fu30b3u30fcu30c9u3092u751fu6210u3059u308bu524du306bu8003u3048u308bu3053u3068u3067u30d7u30edu30f3u30d7u30c8u3092u51e6u7406u3057u307eu3059u3002u30b3u30fcu30c9u751fu6210u304cu5b8cu4e86u3059u308bu3068u3001u30b9u30c8u30eau30fcu30dfu30f3u30b0u306fu505cu6b62u3057u307eu3059u3002

u30e6u30fcu30c6u30a3u30eau30c6u30a3u95a2u6570 file_service.process_html_content u306fu3001u30ecu30b9u30ddu30f3u30b9u5185u306eHTMLu30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u3057u307eu3059u3002u4f5cu6210u3055u308cu305fHTMLu30d5u30a1u30a4u30ebu306fu3001file_service.save_html_file u3092u4f7fu7528u3057u3066u4fddu5b58u3055u308cu3001u7d71u4e00u3055u308cu305fJSONu69cbu9020u306bu683cu7d0du3055u308cu307eu3059u3002u3053u308cu306bu3088u308au3001u53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u30ecu30f3u30c0u30eau30f3u30b2u3057u3001u751fu6210u3055u308cu305fu30b3u30fcu30c9u3092u8868u793au3059u308bu305fu3081u306eu7d20u65e9u3044u53d6u5f97u304cu53efu80fdu306bu306au308au307eu3059u3002
u8a66u9a13u3092u5bb9u6613u306bu3059u308bu305fu3081u306bu3001u300cu518du751fu6210u300du30dcu30bfu30f3u304cu8a2du3051u3089u308cu3066u3044u307eu3059u3002u3053u308cu306fu3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu30d2u30c7u30aau3092u4f7fu7528u3057u3066u5206u6790u3068u30b3u30fcu30c9u751fu6210u30d7u30edu30b2u30b9u3092u518du5ea6u52d5u304bu3057u3001u540cu3058u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u306bu57fau3065u304fu3055u307eu3056u307eu306au53ccu65b9u5411u6027u306eu53efu80fdu6027u3092u63a2u308bu3053u3068u3092u53efu80fdu306bu3057u307eu3059u3002

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3068u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u306eu5225u306eu65b9u6cd5u306fu3001u500bu4ebau306eTwelveLabs APIu30adu30fcu3092u63a5u7d9au3059u308bu3053u3068u3067u3059u3002APIu30adu30fcu304cu63a5u7d9au3055u308cu308bu3068u3001u5e0cu671bu3059u308b index_id u3068u305du308cu306bu95a2u9023u4ed8u3051u3089u308fu305fu7279u5b9au306eu30d2u30c7u30aau3092u9078u629eu3067u304du307eu3059u3002u30d2u30c7u30aau9078u629eu5f8cu3001u5bfeu5fdcu3059u308b video_id u304cu5206u6790u3092u884cu3044u8aacu660eu30c6u30adu30b9u30c8u3092u751fu6210u3059u308bu305fu3081u306bu4f7fu7528u3055u308cu3001u305du306eu5f8cSambanovau30b2u30fcu30e0u30b3u30fcu30c9u751fu6210u30d4u30d7u30e9u30a4u30f3u3092u901au3055u308cu307eu3059u3002u30d5u30a1u30a4u30ebu51e6u7406u30d7u30edu30b2u30b9u306fu3001HTMLu30d5u30a1u30a4u30ebu3092u62bdu51fau3057u3066u4fddu5b58u3059u308bu305fu3081u306bu3001u524du8ff0u306eu3082u306eu3068u540cu69d8u3067u3059u3002
u81eau8eabu306eu30d2u30c7u30aau3067u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u4f7fu7528u3059u308bu306bu306fu3001u307eu305aTwelveLabs Playgroundu3092u4ecbu3057u3066u30a4u30f3u30c7u30c3u30afu30b9IDu3092u751fu6210u3057u3001u30d2u30c7u30aau3092u30a2u30c3u30d7u30edu30fcu30c9u3057u3066u30a4u30f3u30c7u30c3u30afu30b9u5316u3059u308bu3053u3068u3092u63a8u5968u3057u307eu3059u3002u305du308cu304cu5b8cu4e86u3057u305fu3089u3001u3053u3053u306bAPIu30adu30fcu3092u63a5u7d9au3057u3066u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu6a5fu80fdu3092u5145u5206u306bu6d3bu7528u3057u3066u304fu3060u3055u3044u3002
u6e96u5099u624bu9806
TwelveLabs Playgroundu304bu3089APIu30adu30fcu3092u53d6u5f97u3057u3001u74b0u5883u5909u6570u3092u8a2du5b9au3057u307eu3059u3002
TwelveLabs Playgroundu3092u4ecbu3057u3066pegasus-1.2u3092u9078u629eu3057u3001u30a4u30f3u30c7u30c3u30afu30b9u3092u4f5cu6210u3057u307eu3059u3002u305du3057u3066u3001u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u5c02u7528u306eindex_idu3092u53d6u5f97u3057u307eu3059u3002
GitHubu304bu3089u30d7u30edu30b8u30a7u30afu30c8u3092u30afu30edu30fcu30f3u3057u307eu3059u3002
SambaNovau30c0u30c3u30b7u30e5u30dcu30fcu30c9u304bu3089APIu30adu30fcu3092u53d6u5f97u3057u307eu3059u3002
TwelveLabsu3068SambaNovau306eu8aadu8a3cu60c5u5831u3092u542bu3080.envu30d5u30a1u30a4u30ebu3092u4f5cu6210u3057u307eu3059u3002
u3053u308cu3089u306eu624bu9806u304cu5b8cu4e86u3059u308bu3068u3001u958bu767au3092u59cbu3081u308bu6e96u5099u306eu6574u3044u307eu3059uff01
Video2Gameu30a2u30d7u30eau306eu89e3u8aac
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau306bu5909u63dbu3059u308bu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu69cbu7bc9u65b9u6cd5u306bu7126u70b9u3092u5f53u3066u307eu3059u3002u30a2u30d7u30eau306fu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bNext.jsu3001u30d0u30c3u30afu30a8u30f3u30c3u30c9u306bCORSu3092u6709u52b9u306bu3057u305fFlask APIu3092u4f7fu7528u3057u3066u3044u307eu3059u3002u3053u3053u3067u306fu3001Video2Gameu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4e2du6838u30d0u30c3u30afu30a8u30f3u30c3u30c9u30e6u30fcu30c6u30a3u30eau30c6u30a3u306eu5b9fu88c5u3068u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30bbu30c3u30c8u30a2u30c3u30d7u306bu7126u70b9u3092u5f53u3066u307eu3059u3002
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001SambaNovau3092u4ecbu3057u3066u30a2u30afu30bbu30b9u3059u308bu3053u3068u3067u3001u30b2u30fcu30e0u30b3u30fcu30c9u751fu6210u306bu9ad8u901fu63a8u8ad6LLMu3092u4f7fu7528u3059u308bu65b9u6cd5u306bu7126u70b9u3092u5f53u3066u307eu3059u3002u305du306eu30a2u30afu30bbu30b9u304cu3044u304bu306bu7c21u5358u304bu3092u898bu3066u307fu307eu3057u3083u3046u3002u8a73u7d30u306au30b3u30fcu30c9u69cbu9020u3068u30bbu30c3u30c8u30a2u30c3u30d7u6280u8853u306bu3064u3044u3066u306fu3001GitHubu306e README.md u3092u3054u78bau8a8du304fu3060u3055u3044u3002
1 - u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fTwelveLabsu306eu30d2u30c7u30aau304bu3085u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau3092u751fu6210u3059u308bu65b9u6cd5
1.1 u5fc5u898au306au8a2du5b9au3092u884cu3046
u3059u3079u306eu306eu5fc5u898au306au8a2du5b9au306f config.py u3067u5b9au7fa9u3055u308cu3001u74b0u5883u5909u6570u304bu3089u5024u304cu30edu30fcu30c9u3055u308cu307eu3059u3002u3053u306eu96c6u4e2du5316u3055u308cu305fu8a2du5b9au30a2u30d7u30edu30fcu30c1u306bu3088u308au3001u3059u3079u306eu5909u6570u306bu7c21u5358u306bu30a2u30afu30bbu30b9u3067u304du3001u7d20u6674u3089u3057u304fu6574u7406u3055u308cu7ba1u7406u3057u3084u3059u3044u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu30bbu30c3u30c8u30a2u30c3u30d7u3092u7dadu6301u3067u304du307eu3059u3002
backend/app/config.py (7-24 u884cu76ee)
class Config: ` # API credentials loaded from environment variables TWELVELABS_API_KEY = os.getenv("TWELVELABS_API_KEY") SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY") TWELVELABS_INDEX_ID = os.getenv("TWELVELABS_INDEX_ID") SAMBANOVA_BASE_URL=os.getenv("SAMBANOVA_BASE_URL") APP_URL = os.getenv("APP_URL", "http://localhost:8000") # Directory paths for file organization GAMES_DIR = "generated_games" # Directory to store generated game files CACHE_DIR = "game_cache" # Directory for caching game-related data INSTRUCTIONS_DIR = "instructions" # # Directory containing prompt files # SambaNova service configuration SAMBANOVA_BASE_URL = SAMBANOVA_BASE_URL SAMBANOVA_MODEL = "DeepSeek-V3-0324" # LLM text generation parameters GENERATION_TEMPERATURE = 0.1 GENERATION_TOP_P = 0.1 GENERATION_MAX_TOKENS = 16000 MIN_HTML_LENGTH = 7000
TwelveLabsu3068SambaNovau306eu8aadu8a3cu60c5u5831u3092u8a2du5b9au3057u305fu5f8cu3001INSTRUCTIONS_DIR u304cu521du671fu5316u3055u308cu307eu3059u3002u3053u306eu30c1u30ecu30afu30c8u30eau306bu306fu3001u30d7u30edu30b2u30b9u5168u4f53u3067u4f7fu7528u3055u308cu308bu3059u3079u306eu4e8eu5148u306bu5b9au7fa9u3055u308cu305fu30d7u30edu30f3u30d7u30c8u304cu542bu305eu308cu307eu3059u3002u751fu6210u3055u308cu305fu3059u3079u306eu53ccu65b9u5411u30b2u30fcu30e0u306f GAMES_DIR u306bu4fddu5b58u3055u308cu3001CACHE_DIR u306bu30adu30e3u30c3u30b7u30e5u3055u308cu307eu3059u3002
u30b3u30fcu30c9u751fu6210u306bu4f7fu7528u3055u308cu308bu30e2u30c7u30ebu306f DeepSeek-V3-0324 u3067u3042u308au3001u30e9u30f3u30c0u30e0u6027u3092u6e1bu3089u3059u305fu3081u306b 0.1 u306eu6e29u5ea6u304cu8a2du5b9au3055u308cu3001max_tokens u306eu5236u9650u304cu5b9au7fa9u3055u308cu3066u3044u307eu3059u3002u3057u8a66u3057u3066u307fu305fu3044u5834u5408u306fu3001u3053u308cu3089u306eu30d1u30e9u30e1u30fcu30bfu3092u5a09u66f4u3059u308bu304bu3001u8a2du5b9au5185u3067u5225u306eu30e2u30c7u30ebu306bu5207u308au66ffu3048u308bu3053u306eu304cu3067u304du307eu3059u3002
1.2 u30a4u30f3u30c7u30c3u30afu30b9u3092u53d6u5f97u3059u308b
u30e2u30fcu30b6u30fcu304cu30ddu30fcu30bfu30ebu3092u4ecbu3057u3066TwelveLabs APIu30adu30fcu3092u63a5u7d9au305bu308cu3070u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu305du308cu3092u4f7fu7528u3057u3066u30a2u30abu30a6u30f3u30c8u306bu95a2u9023u4ed8u3051u3089u308fu305fu3059u3079u306eu30a4u30f3u30c7u30c3u30afu30b9u3092u53d6u5f97u3057u307eu3059u3002u305du306eu5f8cu3001u30ecu30b9u30ddu30f3u30b9u304cu69cbu9020u5316u3055u308eu3001u8868u793au3059u308bu305fu3081u306bu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu9001u4fe1u3055u308cu307eu3059u00e3u3002
def get_indexes(self): try: print("Fetching indexes...") # Use direct HTTP request if not self.api_key: print("No API key available") return [] # To get the list of indexes url = "https://api.twelvelabs.io/v1.3/indexes" headers = { "accept": "application/json", "x-api-key": self.api_key } response = requests.get(url, headers=headers) if response.status_code == 200: data = response.json() result = [] # Structuring the relevant information needed for index in data.get('data', []): result.append({ "id": index['_id'], "name": index['index_name'] }) return result else: print(f"Failed to fetch indexes: Status {response.status_code}") return [] except Exception as e: print(f"Error fetching indexes: {e}") return []
1.3 u9078u629eu3055u308cu305f index_id u306bu5bfeu5fdcu3059u308bu30d2u30c7u30aau3092u53d6u5f97u3059u308b
u30e2u30fcu30b6u30fcu304cu30a4u30f3u30c7u30c3u30afu30b9u3092u9078u629eu3059u308bu3068u3001u5bfeu5fdcu3059u308b index_id u304cu30adu30e3u30d7u30c1u30e3u3055u308cu307eu3059u3002u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u751fu6210u3059u308bu306bu306fu3001u305du306eu30a4u30f3u30c7u30c3u30afu30b9u304bu3089u7279u5b9au306eu30d2u30c7u30aau3092u9078u629eu3059u308bu3053u306eu304cu3042u308au307eu3059u3002u9078u629eu3055u308cu305f index_id u3092u4f7fu7528u3057u3066u3001u305du306eu30a4u30f3u30c7u30c3u30afu30b9u306bu95a2u9023u4ed8u3051u3089u308fu305fu3059u3079u306eu30d2u30c7u30aau3092u53d6u5f97u3059u308bu305fu3081u306bu3001u305du306eu30e1u30bdu30c3u30c9u304cu547cu3073u51fau3055u308cu307eu3059u3002
def get_videos(self, index_id): try: # Use direct HTTP request if not self.api_key: print("No API key available") return [] # List of Videos info of that respective index id url = f"https://api.twelvelabs.io/v1.3/indexes/{index_id}/videos" headers = { "accept": "application/json", "x-api-key": self.api_key } response = requests.get(url, headers=headers) if response.status_code == 200: data = response.json() result = [] for video in data.get('data', []): system_metadata = video.get('system_metadata', {}) # Structuring the response to get relevant information to showcase on the frontend result.append({ "id": video['_id'], "name": system_metadata.get('filename', f'Video {video["_id"]}'), "duration": system_metadata.get('duration', 0) }) return result else: print(f"Failed to fetch videos: Status {response.status_code}") return [] except Exception as e: print(f"Error fetching videos for index {index_id}: {e}") return []
u30d2u30c7u30aau3092u9078u629eu3059u308bu3068u3001video_id u304fu305du306eu30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u306eu305du306eu5f8cu306eu5206u6790u30d7u30edu30b2u30b9u306bu9001u4fe1u3055u308cu307eu3059u3002
1.4 pegasus-1.2 u3067u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u5206u6790u3059u308b
u30a2u30cau30e9u30a4u30bau30e6u30fcu30c6u30a3u30eau30c6u30a3u306eu76eeu7684u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u3057u3001u305du306eu30b3u30f3u30c6u30adu30b9u30c8u306bu57fau3065u3044u3066u6709u610fu7fa9u306eu3042u308bu6307u793au3092u751fu6210u3059u308bu3053u306eu3067u3059u3002u3053u308cu3089u306eu6307u793au306fu3001u53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u69cbu7bc9u3059u308bu305fu3081u306eu57fau790eu3068u306au308au3001u305du306eu5f8cu306eu30b3u30fcu30c9u751fu6210u30d7u30edu30b2u30b9u3092u5c0eu304du307eu200bu200bu3059u3002u3053u306eu5206u6790u306bu4f7fu7528u3055u308cu308bu30d7u30edu30f3u30d7u30c8u306fu3001u30d0u30c3u30afu30a8u30f3u30c3u30c9u3067u30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u3068u3057u3066u4e8eu514au306bu5b9au7fa9u3055u308cu3066u3044u307eu3059u3002u3053u3061u3089u3067u3001u5206u6790u30d7u30edu30f3u30d7u30c8 u304cu78bau8a8du3067u304eu307eu3059u3002
def analyze_video(self, video_id, prompt): try: # Send video analysis request to TwelveLabs API with custom prompt analysis_response = self.client.analyze( video_id=video_id, prompt=prompt ) return analysis_response.data except Exception as e: print(f"Error analyzing video {video_id}: {e}") raise e
video_id u3068u30d7u30edu30f3u30d7u30c8u306fu3001self.client.analyze u306bu30d1u30e9u30e1u30fcu30bfu3068u3057u3066u63d0u4f9bu3055u308cu3001u305du306eu30e1u30bdu30c3u30c9u304cu30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u30fbu5206u6790u3057u3066u6307u793au7d50u679cu3092u751fu6210u3057u307eu3059u3002
1.5 SambaNova u3092u4f7fu7528u3057u305fu53ccu65b9u5411u30b2u30fcu30e0u30b3u30fcu30c9u306eu751fu6210
u5206u6790u7d50u679cu3092u53d7u3051u53d6u308bu306fu3058u3081u308bu3068u3001u751fu6210u3055u308cu305fu30b3u30fcu30c9u30e6u30fcu30c6u30a3u30eau30c6u30a3u304cu200bu200bu30c8u30eau30acu30fcu3055u308cu307eu3059u3002u3053u306eu624bu9806u3067u306fu3001u514au306bu5b9au7fa9u3055u308cu305fu30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u3068u3068u3082u306bu3001u5206u6790u51fau529bu304cu30e2u30fcu30b6u30fcu30d7u30edu30f3u30d7u30c8u3068u3057u3066u9001u3089u308cu307eu3059u3002u4f7fu7528u3055u308cu308bu30e2u30c7u30eb DeepSeek-V3-0324 u306fu3001u524du8ff0u306eu624bu98061.1u3067u8a2du5b9au3057u305fu3082u306eu3068u540cu3058u3067u3001u3059u3002
u3053u306e u30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8 u306fu3001u51fau529bu306eu4e2du6838u306eu8981u4ef6u3068u671fu5f85u3055u308cu308bu69cbu9020u3092u69cbu60f3u3057u3001u30e2u30c7u30ebu304cu30bfu30b9u30afu306eu76eeu7684u3068u5236u7d04u3092u7406u89e3u3057u3066u3044u308bu3053u306eu3092u78bau4fddu3057u307eu3059u3002u4e00u65b9u3067u3001u30e2u30fcu30b6u30fcu30d7u30edu30f3u30d7u30c8 u306fu3001u5206u6790u7d50u679cu306bu52a0u3048u3001u30ecu30a4u30a2u30a6u30c8u3001u30c7u30b6u30a4u30f3u3001u914du8272u3001u30d5u30a9u30fcu30deu30c3u30c8u306bu95a2u3059u308bu8a73u7d30u306au8ffdu52a0u6307u793au3092u7d44u307fu8fbcu3093u3067u3044u307eu3059u3002u3053u308cu3089u306eu30d7u30edu30f3u30d7u30c8u304cu5fc5u898au306bu5fdcu3058u3066u3001u30e2u30c7u30ebu3092u30acu30a4u30c9u3057u3066u3001u7126u70b9u304cu7d5eu3089u308cu305fu6574u7406u3055u308cu305fu53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u751fu6210u3057u307eu3059u3002
def generate_game_stream(self, system_prompt, user_prompt): print("Starting streaming generation...") if not self._test_api_connection(): yield "Error: Sambanova API is not reachable" return try: start_time = time.time() response = self.client.chat.completions.create( model=current_app.config['SAMBANOVA_MODEL'], messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt} ], temperature=current_app.config['GENERATION_TEMPERATURE'], top_p=current_app.config['GENERATION_TOP_P'], max_tokens=current_app.config['GENERATION_MAX_TOKENS'], stream=True ) print(f"API call initiated in {time.time() - start_time:.2f}s") chunk_count = 0 total_content = "" last_chunk_time = time.time() for chunk in response: current_time = time.time() if current_time - last_chunk_time > 30: # 30 second timeout print(f"No chunk received for 30 seconds, breaking...") break delta = getattr(chunk.choices[0], 'delta', None) content = getattr(delta, 'content', '') if delta else '' if content: chunk_count += 1 total_content += content last_chunk_time = current_time # Print live streaming progress if chunk_count % 20 == 0: # Print every 20 chunks print(f"Stream: {chunk_count} chunks, {len(total_content)} chars") yield content print(f"Streaming completed: {chunk_count} chunks, {len(total_content)} total chars") print(f"Total streaming time: {time.time() - start_time:.2f}s") except Exception as e: error_msg = f"Streaming error: {str(e)}" print(error_msg) print(f"Error type: {type(e).__name__}") if hasattr(e, 'response'): print(f"Response status: {e.response.status_code}") print(f"Response text: {e.response.text}") yield error_msg
SambaNova u306e API u3092 stream=True u3067u547cu3073u51fau3059u3068u3001u751fu6210u3055u308cu305fu30b3u30f3u30c6u30f3u30c4u306fu4f5cu6210 u3055u308cu305fu9806u306bu5206u5272u3055u308cu3066u9001u308au8fd4u3055u308cu3001u3053u306eu95a2u6570u304cu305du308cu3092u3059u3050u306bu30e2u30fcu30b6u30fcu306bu8ff4u3057u307eu3059u3002u898bu4e8bu306au306eu306fu3001u5185u8535u3055u308cu305fu5b89u5168u5b9au4fddu6a5fu69cbu3067u3059u3002u30deu30c3u30c1u30f3u30b0u306eu7121u99c4u306au547cu3073u51fau3059u3092u907fu3051u308bu305fu3081u306bu3001u307eu305a API u63a5u7d9au3092u30c6u30b9u30c8u3057u3001u8a70u307eu3063u305fu63a5u7d9au3092u635eu3046u305fu3081u306b 30 u79d2u306eu30bfu30a4u30e0u30a2u30a6u30c8u3092u5b9fu88c5u3057u300120 u30c1u30e3u30f3u30afu3054u3068u306bu8a73u7d30u306au30e1u30c8u30eau30afu30b9u3092u8a18u9332u3059u308bu305fu3081u3001u30d1u30d5u30a9u30fcu30deu30f3u30b9u3092u30eau30a2u30ebu30bfu30a4u30e0u3067u76e3u8996u3067u3042u308au307eu3059u00e3u3002
1.6 u751fu6210u306eu305fu3081u306eu95a2u6570u547cu3073u51fau3057u30d4u30d7u30e9u30a4u30f3
u3053u306eu30bbu30afu30b7u30e7u30f3u3067u306fu3001u524du8ff0u306eu30e2u30fcu30c6u30a3u30eau30c6u30a3u95a2u6570u304cu547cu3073u51fau3055u308cu5b9fu884cu3055u308cu308bu3001u30d7u30edu30b2u30b9u306eu5168u4f53u30d4u30d7u30e9u30a4u30f3u306bu3064u3044u3066u8aacu660eu3057u307eu3059u3002u3053u308cu306fu3001u5206u6790u306bu5fc5u898au306a video_id u3068u95a2u9023u4ed8u3051u3089u308fu305f API u30adu30fcu306eu5b58u5728u3092u691cu8a3cu3059u308bu3053u306eu304bu3089u59cbu307eu308au307eu3059u3002u78bau8a8du3055u308cu308bu306fu3058u3081u308bu3068u3001u5206u6790u30d7u30edu30f3u30d7u30c8u304fu304cu30ddu30fcu30c9u3055u308cu3001analyze_video u30aau30fcu30c6u30a3u30eau30c6u30a3u304cu30aau30eau30acu30fcu3055u308cu3066u6307u793au7d50u679cu3092u751fu6210u3057u307eu3059u3002u305du306eu5f8cu3001SambaNova u30b7u30b9u30c6u30e0 u30d7u30edu30f3u30d7u30c8u304cu30ddu30fcu30c9u3055u308cu3001u30b3u30fcu30c9u751fu6210 u30d7u30edu30b2u30b9u3092 u958bu59cbu3059u308bu30bfu30e1u306bu4f7fu7528u3055u308cu307eu3059u3002SambaNova u304bu3089u306eu7d50u679cu306fu30c1u30e3u30f3u30afu3054u3068u306bu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu30b9u30c8u30eau30fcu30dfu30f3u30b0u3055u308cu3001u30e2u30fcu30b6u30fcu306fu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30e9u30a4u30d6u751fu6210u3092u898bu308bu3053u306eu304cu3067u304du307eu3059u3002
u751fu6210u304fu5b8cu4e86u3057u30b9u30c8u30eau30fcu30dfu30f3u30b0 u304cu7d42u308fu308bu3068u3001u30e6u30fcu30c6u30a3u30eau30c6u30a3 u95a2u6570 file_service.process_html_content u304cu30ecu30b9u30ddu30f3u30b9u304bu3089 HTML u30b3u30f3u30c6u30f3u30c4 u3092u62bdu51fau3057u307eu3059u3002u3053u306eu62bdu51fau3055u308cu305f HTML u306fu3001file_service.save_html_file u3092u4f7fu7528u3057u3066u5225u30d5u30a1u30a4u30ebu3068u3057u3066u4fddu5b58u3055u308cu307eu3059u3002u4fddu5b58u3055u308cu305f HTML u30d1u30b9u3068u3068u3082u306bu3001video_idu3001video_analysisu3001u304au3088u3073u95a2u9023u3059u308bu30e1u30bf u30c7u30fcu30bfu306au3069u306eu4ed6u306eu95a2u9023u3059u308bu8a73u7d30u306fu3001u5f8cu3067u7c21u5358u306bu53d6u5f97 u3067u304du308bu3088u3046u306bu7d71u4e00u3055u308cu305f JSON u30d5u30a1u30a4u30ebu306b u683cu7d0du3055u308cu307eu3059u3002
@api_bp.route('/twelvelabs/regenerate', methods=['POST', 'GET']) @handle_errors def twelvelabs_regenerate(): from app.services.sample_games_service import SampleGamesService from app.services.twelvelabs_service import TwelveLabsService from app.services.sambanova_service import SambanovaService from app.services.file_service import FileService def event_stream(video_id, api_key): # Initialize service for managing generated games, consisting the loading the file handling sample_games_service = SampleGamesService() # Validate required parameters before processing if not video_id: yield f"event: error\ndata: video_id is required\n\n" return if not api_key: yield f"event: error\ndata: API key is required\n\n" return try: # Step 1 - Analyze video content using TwelveLabs yield f"event: progress\ndata: Starting analysis with TwelveLabs...\n\n" # Initialize TwelveLabs service with provided API key twelvelabs_service = TwelveLabsService(api_key=api_key) # Get analysis prompt template and analyze the video analysis_prompt = current_app.prompt_service.get_prompt('analysis') video_analysis = twelvelabs_service.analyze_video(video_id, analysis_prompt) yield f"event: analysis\ndata: {video_analysis}\n\n" # Step 2 - Generate game code using SambaNova AI yield f"event: progress\ndata: Generating game with SambaNova...\n\n" sambanova_service = SambanovaService() # Prepare prompts for game generation using video analysis game_generation_prompt = current_app.prompt_service.get_prompt('game_generation', video_analysis=video_analysis) system_prompt = current_app.prompt_service.get_prompt('system') try: # Stream game generation in real-time chunks streamed_html = "" # Process each chunk of generated content as it arrives for chunk in sambanova_service.generate_game_stream(system_prompt, game_generation_prompt): if chunk: streamed_html += chunk # Send each chunk to client for real-time display yield f"event: game_chunk\ndata: {chunk}\n\n" # Step 3 - Save and process the complete generated game if streamed_html: # Process and clean up the generated HTML content file_service = FileService() html_content = file_service.process_html_content(streamed_html) # Save HTML file to disk with video ID as identifier html_file_path = file_service.save_html_file(html_content, video_id) # Create game metadata and save to file storage game_data = sample_games_service.create_game_data( video_id, video_analysis, html_file_path, twelvelabs_video_ids=[video_id], youtube_url='', video_title=f'TwelveLabs Video {video_id}', channel_name='TwelveLabs', view_count='Generated' ) sample_games_service.save_game(game_data) else: # No content was generated - report error to client yield f"event: error\ndata: No game content was generated\n\n" return except Exception as e: print(f"Error in SambaNova streaming: {str(e)}") yield f"event: error\ndata: Error streaming from SambaNova: {str(e)}\n\n" return yield f"event: done\ndata: [DONE]\n\n" except Exception as e: print(f"Error in TwelveLabs processing: {str(e)}") yield f"event: error\ndata: Error processing TwelveLabs video: {str(e)}\n\n" # Handle different HTTP methods for parameter extraction if request.method == 'GET': video_id = request.args.get('video_id') api_key = request.args.get('api_key') else: data = request.get_json() video_id = data.get('video_id') api_key = request.headers.get('X-Twelvelabs-Api-Key') if not video_id: return jsonify({"error": "video_id is required"}), 400 return Response(stream_with_context(event_stream(video_id, api_key)), mimetype='text/event-stream')
u751fu6210u30d7u30edu30b2u30b9 u304cu5b8cu4e86u3057 u30c1u30a7u30f3u30afu51e6u7406u304c u305du308cu305eu308cu7d42u308fu308bu3068u3001u751fu6210u3055u308cu305fu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3 u3068u305du306e u30b3u30fcu30c9u306f u4fddu5b58u3055u308cu305f JSON u304bu3089 u30edu30fcu30c9u3055u308cu3001u30ddu30fcu30bfu30eb u4e0au306bu30ecu30f3u30c0u30eau30f3u30b0u3055u308cu307eu3059u3002
2 - YouTubeURLu3092u4ecbu3057u3066u751fu6210u3059u308bu30bfu30e1u306eu95a2u6570u547cu3073u51fau3057u30d4u30d7u30e9u30a4u30f3
u30a4u30f3u30bfu30e9u30afu30c6u30a3u30d6u306au5b66u7fd2u30a2u30d7u30eau3092u751fu6210u3059u308bu30bfu30e1u306b YouTube u306e URL u3092u4f7fu7528u3059u308bu3084u3046u306au4ee3u66ffu624bu6bb5u3067u3082u3001u5168u4f53u306eu30d4u30d7u30e9u30a4u30f3u306fu307bu3068u3093u3069u540cu3058u3067u3059u3002u4e3bu306au9055u3044u306fu521du671fu306eu624bu9806u306bu3042u308au307eu3059u3002u30d2u30c7u30aau306fu307eu305a u51e6u7406u3055u308c u30edu30fcu30abu30eb u307eu305fu306f u30b5u30fcu30d0u30fc u306b u4fddu5b58u3055u308cu3001u305du306eu5f8c TwelveLabs API u3092u4f7fu7528u3057u3066 u30a4u30f3u30c7u30c3u30afu30b9u5316 u3055u308cu307eu3059u3002u30b5u30ddu30fcu30c8u3055u308cu3066u3044u308b u30d7u30e9u30c3u30c8u30d5u30a9u30fcu30e0 URL u304bu3089 u30d2u30c7u30aau306e u30c0u30a6u30f3u30edu30fcu30c9u3092 u51e6u7406u3059u308b u30e6u30fcu30c6u30a3u30eau30c6u30a3u3092 u7d44u307fu8fbcu3080 u3053u306eu304fu3001u305du306eu5f8c u30a4u30f3u30c7u30c3u30afu30b9u5316u306e u5fc5u898au306a u624bu9806 u304cu8a2du5b9au3055u308b u3053u306eu304cu3042u308au307eu3059u3002
u30a4u30f3u30c7u30c3u30afu30b9u5316u304cu3069u306eu3088u3046u306bu884cu308fu308cu308bu304bu3092u7406u89e3u3059u308bu306bu306fu3001u4ee5u4e0bu306eu30b3u30fcu30c9u30b9u30cbu30c3u30dau30c3u30c8u3092u53c2u7167u3057u3066u304fu3060u3055u3044u3002
def _index_video_file(self, file_path, index_id): try: # Create a new indexing task for the video file task = self.twelvelabs_service.client.task.create( index_id=index_id, file=file_path, ) print(f"Indexing task created: {task.id}") max_wait_time = 900 start_time = time.time() while time.time() - start_time < max_wait_time: task = self.twelvelabs_service.client.task.retrieve(task.id) # Handle different task status outcomes if task.status == "ready": print(f"Indexing completed successfully. Video ID: {task.video_id}") # Indexing completed successfully - video is now searchable/analyzable return task.video_id elif task.status == "failed": print(f"Indexing failed: {task.status}") return None elif task.status in ["processing", "pending"]: elapsed = int(time.time() - start_time) print(f"Indexing in progress... Status: {task.status} (Elapsed: {elapsed}s)") time.sleep(15) else: print(f"Unknown status: {task.status}") time.sleep(10) print("Indexing timed out") return None except Exception as e: print(f"Error during video indexing: {str(e)}") return None
YouTube URL u304bu3089 u53ccu65b9u5411u30a2u30d7u30ea u751fu6210u307eu3067u306e u5b8cu5168u306a u30d7u30edu30b2u30b9 u30d4u30d7u30e9u30a4u30f3u306fu3001u3053u3061u3089u3067 u78bau8a8du3067u304du307eu3059u3002
YouTube URL u30d2u30c7u30aa u5411u3051u306e u518du751fu6210 u6a5fu80fdu306fu3001u30d2u30c7u30aau304c u3059u3067u306b u30a4u30f3u30c7u30c3u30afu30b9u5316 u3055u308cu3001u518du5206u6790 u3084 u518du751fu6210 u306e u6e96u5099u304c u6574u3063u3066u3044u308b u305fu3081u3001u524du8ff0u306e u3082u306eu3068 u5168u304f u540cu3058 u3088u3046u306b u52d5u4f5cu3057u307eu3059u3002
u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u306eu89e3u8aac u3092 u6df1u3081u308b u306eu306b u5f79u7acbu3061u3001u30d2u30c7u30aau3092 u4f53u9a13 u3057 u30a4u30f3u30bfu30e9u30afu30c8 u3057 u5b66u3073 u904au3076u3001 u307eu3063u305fu304f u65b0u3057u3044 u65b9u6cd5 u3092 u63d0u4f9bu3059u308b u30ddu30fcu30c3u30eb u306e u6a5fu80fdu3092 u30b9u30b0 u306b u78bau8a8du3057u307eu3057u3087u3046u3002

u30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u8a66u3059u30bfu30e1u306e u3055u3089u306au308b u30a2u30a4u30c7u30a2
u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u304cu3069u306eu3088u3046u306b u53ccu65b9u5411u306e u4f53u9a13u306b u5909u308fu308bu304b u3092u7406u89e3u3059u308b u3053u306eu306fu3001u3088u308a u9b45u529bu7684u306eu3001 u305du3057u3066 u5fc5u898au306bu5fdcu3058u305f u5b66u7fd2u306e u9053u3092 u958bu304du307eu3059u3002u30a2u30cau30e9u30a4u30ba u30a8u30f3u30b8u30f3 u3068 Sambanova u3092 u4f7fu3063u3066 u8a66u3059u3053u306eu304cu3067u304du308b u5b9fu9a13u7684u306a u65b9u5411 u306fu3001u4ee5u4e0bu306eu901au308a u3067u3059uff1a
ud83cudfae u30d5u30a3u30fcu30c9u30d0u30c3u30af u30ebu30fcu30d7 u306bu3088u308b u9ad8u901fu306a u30a4u30c6u30ecu30fcu30b7u30e7u30f3 u2014 SambaNovau3092 u6d3bu7528u3057u305f u30b2u30fcu30e0u30b3u30fcu30c9u751fu6210u30ebu30fcu30d7u306bu3001u30e2u30fcu30b6u30fc u30d5u30a3u30fcu30c9u30d0u30c3u30af u3092 u76f4u63a5 u7d44u307fu8fbcu307fu307eu3059u3002 u3000
ud83dudd0d u6df1u3044 u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u306e u7814u7a76 u2014 u9ad8u901fu63a8u8ad6u30e2u30c7u30ebu3092 u4f7fu3063u3066 u30d2u30c7u30aa u5206u6790 u306e u8a73u7d30u306a u89e3u8aac u3092u884cu3044u307eu3059u3002u4e3bu306a u610fu898b u3092 u81eau52d5u7684u306b u62bdu51fau3057u3001u53c2u7167 u3092 u7279u5b9au3057u3001u95a2u9023u3059u308b u5f15u7528 u3084 u5916u90e8u306e u5b66u7fd2u8cc7u6599 u3092 u660eu3089u304bu306b u3057u307eu3059u3002
ud83eudde0 u30d2u30c7u30aa Agentic AI u2014 u30a8u30fcu30b8u30a7u30f3u30c8u30d4u30d7u30e9u30a4u30f3 u306e u4e00u90e8u3068u3057u3066 u63a8u8ad6u30d9u30fcu30b9 u306e u63a8u8ad6u30e2u30c7u30ebu3092 u7d45u5408 u3057u307eu3059u3002u3053u308cu306bu3088u308au3001 u30b7u30b9u30c6u30e0 u306fu30d2u30c7u30aau7de8u96c6u306e u5909u63db u306bu5fc5u898au306a u8a08u753b u3092 u7acbu3066u3001u8abfu6574u3057u3001 u9069u5207u306a u30c4u30fcu30eb u3092 u4f7fu3046 u3053u306eu304cu3067u304du307eu3059u3002
u304au308fu308au306b
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu306fu3001u30d2u30c7u30aau7406u89e3u304cu3001 u79c1u305fu3061 u304cu5b66u3073 u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u3068 u30a4u30f3u30bfu30e9u30afu30c8 u3059u308b u65b9u6cd5 u3092u3001 u3069u306eu3088u3046u306b u518du5b9au7fa9 u3067u304du308b u304bu3092 u63a2u308a u307eu3059u3002 u30d2u30c7u30aa u5206u6790 u751fu6210u306e u305fu3081u306b TwelveLabs u3092u3001u305du3057u3066 u9ad8u301fu306a u30b3u30fcu30c9u30d9u30fcu30b9 u30b2u30fcu30e0 u751fu6210 u306e u305fu3081u306b SambaNova u3092 u7d44u307fu5408u308fu305bu308b u3053u306eu3067u3001 u53d7u52d5u7684u306e u6559u80b2u30d2u30c7u30aau3092 u53ccu65b9u5411u306e u30b2u30fcu30e0u578b u5b66u7fd2 u4f53u9a13 u306b u5909u3048u308b u30b7u30b9u30c6u30e0 u3092 u69cbu7bc9 u3057u307eu3057u305fu3002Video2Game u306fu3001 u30deu30ebu30c1u30e2u30fcu30c0u30ebu89e3 u3068u3001 u904au3073 u5fc3 u306e u3042u308b u5b66u3073u3001u30e0 u3092 u7d39u4ecbu3057 u53ccu65b9u306e u67b6u3051u6a4b u3068u306au308bu3053u3068u3067u3001 u5f93u6765u306e u30d2u30c7u30aa u518du751f u3092 u8d85u3048u305f u6c89u6d78 u578b u306e u500bu4ebau5316 u3055u308cu305f u6559u80b2 u3092u63d0u4f9bu3057u307eu3059u3002
u8ffdu52a0u306eu30eau30bdu30fcu30b9
u30d2u30c7u30aa u5206u6790 u30a8u30f3u30b8u30f3 Pegasus-1.2 u306bu3064u3044u3066u3001 u3088u308a u8a73u3057u304f u5b66u3073 u307eu3057u3087u3046u3002TwelveLabs u3092 u3055u3089u306b u63a2u308au3001 u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4 u5206u6790 u306e u7406u89e3u3092 u6df1u3081u308b u30bfu30e1u306bu3001 u3053u308cu3089u306e u30c4u30fcu30eb u3092 u78bau8a8d u3057u3066 u304fu3060u3055u3044uff1a
u3055u3089u306au308b u30e6u30fcu30b9 u30b1u30fcu30b9 u306e u63a2u7d22uff1a SambaNova u30e2u30c7u30eb u30cfu30d6u3092 u8a2au308cu3066u3001 u3055u307eu3056u307eu306a u30e2u30c7u30eb u3068 u30d3u30b8u30cdu30b9 u306e u5ea7u6a19 u306b u5408u308fu305bu305f u985eu4f3cu306e u30efu30fcu30afu30d5u30edu30fcu3092 u3069u306eu3088u3046u306b u5b9fu88c5 u3059u308b u304b u3092 u5b66u3092u307fu3001u63a2u3063u3066u307f u307eu3057u3087u3046u3002
u8a71u3057 u5408u3044u306b u53c2u52a0u3059u308buff1a u3053u306e u7d45u5408 u306b u5c0du3059u308b u30d5u30a3u30fcu30c9u30d0u30c3u30af u3092 TwelveLabs Discordu3067 u5171u6709u3057 u307eu3057u3087u3046u3002
u30c1u30e5u30fcu30c8u30eau30a2u30eb u3092 u63a2u308buff1a u5b8cu5168u306a u30c1u30e5u30fcu30c8u30eau30a2u30eb u3067u3001 TwelveLabs u306e u529b u3092 u3055u3089u306b u6df1u304f u5b66u3073 u307eu3057u3087u3046u3002
u3053u308cu3089u306e u30eau30bdu30fcu30b9 u3092 u4f7fu3063u3066 u77e5u8b5a u3092 u3072u308du3052u3001 TwelveLabs u306e u30d2u30c7u30aau7406u89e3u6280u8853 u3092 u4f7fu3063u305f u9769u65b0u306e u30a2u30d7u30ea u3092 u4f5cu308b u3053u306eu3092 u5fdcu63f4u3057 u307eu3059u3002
u306fu3058u3081u306b
u6559u80b2u30d2u30c7u30aau304cu5358u306bu898bu305bu3066u4f1du3048u308bu3060u3051u3067u306fu306au304fu3001u305du308cu4ee5u4e0au306eu3053u3068u304cu3067u304du308bu3068u3057u305fu3089u3069u3046u3067u3057u3087u3046uff1f ud83cudfae
u53d7u52d5u7684u306au30d2u30c7u30aau8b1bu7fa9u3092u3001u53d7u8b1bu751fu304cu5358u306bu8996u8074u3059u308bu306eu3067u306fu306au304fu3001u30b3u30f3u30bbu30d7u30c8u3092u30d7u30ecu30a4u3057u306au304cu3089u5b66u3076u3001u53ccu65b9u5411u306eu30deu30fcu30e0u30d9u30fcu30b9u306eu5b66u7fd2u4f53u9a13u306bu5909u3048u308bu3053u3068u3092u60f3u50cfu3057u3066u307fu3066u304fu3060u3055u3044u3002
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001TwelveLabsu3092u6d3bu7528u3057u3066u3001YouTubeu306eu6559u80b2u30d2u30c7u30aau3092u9b45u529bu7684u306au5b66u7fd2u30deu30fcu30e0u306bu5909u63dbu3059u308bu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u69cbu7bc9u3057u307eu3059u3002TwelveLabsu30a2u30cau30e9u30a4u30bau30a8u30f3u30b8u30f3u3068u3001SambaNovau306eu63a8u8ad6u30e2u30c7u30ebu3092u7d44u307fu5408u308fu305bu308bu3053u3068u3067u3001u30d2u30c7u30aau304bu3089u6709u610fu7fa9u306au30b3u30f3u30c6u30f3u30c4u3092u62bdu51fau3057u3001u305du308cu3092u53ccu65b9u5411u306eu5b66u7fd2u30e2u30b8u30e5u30fcu30ebu306bu5909u63dbu3059u308bu3053u3068u304cu3067u304du307eu3059u3002
Video2Gameu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u304cu3069u306eu3088u3046u306bu52d5u4f5cu3059u308bu306eu304bu3001u305du3057u3066TwelveLabs Python SDKu3068SambaNovau3092u4f7fu7528u3057u3066u3001u30d2u30c7u30aau7406u89e3u3068u9ad8u901fu63a8u8ad6LLMu3092u7528u3044u305fu540cu69d8u306eu30bdu30eau30e5u30fcu30b7u30e7u30f3u3092u3069u306eu3088u3046u306bu69cbu7bc9u3067u304du308bu304bu3092u63a2u3063u3066u307fu307eu3057u3083u3046u3002
u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30c7u30e2u306fu3053u3061u3089u3067u4f53u9a13u3067u304du307eu3059uff1aVideo2Gameu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3
u524du63d0u6761u4ef6
TwelveLabs Playgroundu306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3066u3001APIu30adu30fcu3092u767au884cu3057u307eu3059u3002
SambaNovau306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3001u30e2u30c7u30ebu306bu30a2u30afu30bbu30b9u3059u308bu305fu3081u306eAPIu30adu30fcu3092u767au884cu3057u307eu3059u3002
u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30eau30ddu30b8u30c8u30eau306fu3001GitHubu30eau30ddu30b8u30c8u30eau3067u78bau8a8du3067u304du307eu3059u3002
Pythonu3001Flasku3001u304au3088u3073Next.jsu306bu7cbeu901au3057u3066u3044u308bu3053u306eu304cu671bu307eu3057u3044u3067u3059u3002
u30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3
u3053u306eu30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u5206u6790u3059u308bu3053u3068u3067u30d2u30c7u30aau7406u89e3u3092u793au3057u3001u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4f5cu6210u3092u652fu63b4u3057u307eu3059u3002u3053u308cu306fu3001u9ad8u901fu63a8u8ad6LLMu306eu30b3u30fcu30c9u751fu6210u306bu3088u3063u3067u884cu308fu308cu307eu3059u3002u30e2u30fcu30b6u30fcu306fu3001TwelveLabsu306eAPIu30adu30fcu3092u63a5u7d9au3059u308bu3053u3068u3067u3001u30d2u30c7u30aau306eURLu3092u63d0u4f9bu3059u308bu304bu3001u307eu305fu306fu3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu30d2u30c7u30aau304bu3089u76f4u63a5u30d2u30c7u30aau3092u9078u629eu3067u304du307eu3059u3002
u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu76eeu7684u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u304bu3089u306eu53ceu30bcu3068u53ccu65b9u5411u6027u3092u5099u3048u305fu65b0u3057u3044u5b66u7fd2u4f53u9a13u3092u63d0u4f9bu3059u308bu3053u3068u3067u3059u3002u3053u3061u3089u3067u3001u30b3u30fcu30c9u306eu8a73u7d30u306au8aacu660eu3068u30c7u30e2u3092u3054u89a7u3044u305fu3060u3051u307eu3059 u2014

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4ed5u7d44u307f
u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f2u3064u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u30e2u30fcu30c9u3092u30b5u30ddu30fcu30c8u3057u3066u3044u307eu3059 u2014
YouTubeu52d5u753bURLu3092u4f7fu7528u3059u308bu5834u5408uff1aYouTubeu52d5u753bu306eURLu3092u63d0u4f9bu3059u308bu3068u3001u30b7u30b9u30c6u30e0u304cu52d5u753bu3092u51e6u7406u30fbu5206u6790u3057u3001SambaNovau3092u4f7fu7528u3057u305fu9ad8u901fu63a8u8ad6LLMu30e2u30c7u30ebu306bu3088u3063u3066u3001u52d5u753bu306bu57fau3065u304fu53ccu65b9u5411u306eu30b2u30fcu30e0u578bu5b66u7fd2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u81eau52d5u751fu6210u3057u307eu3059u3002
TwelveLabs APIu30adu30fcu3092u4f7fu7528u3059u308bu5834u5408uff1au500bu4ebau306eTwelveLabs APIu30adu30fcu3092u63a5u7d9au3057u3066u3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu306fu3058u3081u3066u3044u308bu81eau8eabu306eu52d5u753bu306bu30a2u30afu30bbu30b9u3057u3001u64cdu4f5cu3057u307eu3059u3002u63a5u7d9au3059u308bu3068u3001u65e2u5b58u306eu30a4u30f3u30c7u30c3u30afu30b9IDu3068u5bfeu5fdcu3059u308bu52d5u753bu3092u9078u629eu3067u304du3001u30b7u30b9u30c6u30e0u306fu9078u629eu3055u308cu305fu52d5u753bu30b3u30f3u200bu200bu30c6u30f3u30c4u306bu57fau3065u304fu53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u751fu6210u3057u307eu3059u3002
YouTubeu306eURLu304cu63d0u4f9bu3055u308cu308bu3068u3001u30d2u30c7u30aau306fu307eu305au51e6u7406u3055u308cu3001u30edu30fcu30abu30ebu3067u30b5u30fcu30d0u30fcu306bu4fddu5b58u3055u308cu307eu3059u3002u3053u306eu5f8cu3001u30a4u30f3u30c7u30c3u30afu30b9u5316u30d7u30edu30bbu30b9u304cu59cbu307eu308au3001u30d2u30c7u30aau306fu6307u5b9au3055u308cu305f index_id u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu307eu3059u3002u30a4u30f3u30c7u30c3u30afu30b9u5316u304cu5b8cu4e86u3059u308bu3068u3001video_id u304cu751fu6210u3055u308cu3066u8fd4u3055u308cu3001u305du308cu304cu30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u5206u6790u306bu4f7fu7528u3055u308cu307eu3059u3002
u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u304cu5206u6790u3055u308cu3001u30d2u30c7u30aau7406u89e3u306fu30ecu30a4u30f3u30bau306bu57fau3065u3044u305fu8aacu660eu7684u306au5206u6790u7d50u679cu304cu751fu6210u3055u308cu307eu3059u3002u3053u306eu7d50u679cu306fu3001u53ccu65b9u5411u30b2u30fcu30e0u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu958bu767au3092u6307u5c0eu3059u308bu306eu306bu5f79u7acbu3064u6307u793au3092u63d0u4f9bu3057u307eu3059u3002u5206u6790u30c6u30adu30b9u30c8u306fu3001u30d5u30a9u30fcu30deu30c3u30c8u6307u793au3084u30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u3068u3068u3082u306bu30e2u30fcu30b6u30fcu30d7u30edu30f3u30d7u30c8u306bu542bu305eu308cu307eu3059u3002u3053u306eu30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u306fu3001u751fu6210u3055u308cu308fu305fu51fau529bu304cu5b8cu5168u3067u6a5fu80fdu7684u306au53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3067u3042u308au3001u5206u6790u30c6u30adu30b9u30c8u304bu3089u63a8u5b9au3055u308cu305fu30acu30a4u30c9u30e9u30a4u30f3u3084u6307u793au306bu6e96u62e0u3057u3066u3044u308bu3053u3068u3092u78bau4fddu3057u307eu3059u3002
u305du306eu5f8cu3001SambaNovau3092u901au3058u3066u30b3u30fcu30c9u751fu6210u30d7u30edu30b2u30b9u304cu958bu59cbu3055u308cu3001HTMLu3001CSSu3001u30cau30d0u30b9u30afu30eau30d7u30c8u3092u542bu3080u5358u4e00u306eHTMLu30d5u30a1u30a4u30ebu304cu4f5cu6210u3055u308cu307eu3059u3002u3053u3053u3067u4f7fu7528u3055u308cu308bu30e2u30c7u30ebu306f DeepSeek-V3-0324 u3067u3042u308au3001u9069u5207u306fu30b3u30fcu30c9u3092u751fu6210u3059u308bu524du306bu8003u3048u308bu3053u3068u3067u30d7u30edu30f3u30d7u30c8u3092u51e6u7406u3057u307eu3059u3002u30b3u30fcu30c9u751fu6210u304cu5b8cu4e86u3059u308bu3068u3001u30b9u30c8u30eau30fcu30dfu30f3u30b0u306fu505cu6b62u3057u307eu3059u3002

u30e6u30fcu30c6u30a3u30eau30c6u30a3u95a2u6570 file_service.process_html_content u306fu3001u30ecu30b9u30ddu30f3u30b9u5185u306eHTMLu30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u3057u307eu3059u3002u4f5cu6210u3055u308cu305fHTMLu30d5u30a1u30a4u30ebu306fu3001file_service.save_html_file u3092u4f7fu7528u3057u3066u4fddu5b58u3055u308cu3001u7d71u4e00u3055u308cu305fJSONu69cbu9020u306bu683cu7d0du3055u308cu307eu3059u3002u3053u308cu306bu3088u308au3001u53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u30ecu30f3u30c0u30eau30f3u30b2u3057u3001u751fu6210u3055u308cu305fu30b3u30fcu30c9u3092u8868u793au3059u308bu305fu3081u306eu7d20u65e9u3044u53d6u5f97u304cu53efu80fdu306bu306au308au307eu3059u3002
u8a66u9a13u3092u5bb9u6613u306bu3059u308bu305fu3081u306bu3001u300cu518du751fu6210u300du30dcu30bfu30f3u304cu8a2du3051u3089u308cu3066u3044u307eu3059u3002u3053u308cu306fu3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu30d2u30c7u30aau3092u4f7fu7528u3057u3066u5206u6790u3068u30b3u30fcu30c9u751fu6210u30d7u30edu30b2u30b9u3092u518du5ea6u52d5u304bu3057u3001u540cu3058u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u306bu57fau3065u304fu3055u307eu3056u307eu306au53ccu65b9u5411u6027u306eu53efu80fdu6027u3092u63a2u308bu3053u3068u3092u53efu80fdu306bu3057u307eu3059u3002

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3068u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u306eu5225u306eu65b9u6cd5u306fu3001u500bu4ebau306eTwelveLabs APIu30adu30fcu3092u63a5u7d9au3059u308bu3053u3068u3067u3059u3002APIu30adu30fcu304cu63a5u7d9au3055u308cu308bu3068u3001u5e0cu671bu3059u308b index_id u3068u305du308cu306bu95a2u9023u4ed8u3051u3089u308fu305fu7279u5b9au306eu30d2u30c7u30aau3092u9078u629eu3067u304du307eu3059u3002u30d2u30c7u30aau9078u629eu5f8cu3001u5bfeu5fdcu3059u308b video_id u304cu5206u6790u3092u884cu3044u8aacu660eu30c6u30adu30b9u30c8u3092u751fu6210u3059u308bu305fu3081u306bu4f7fu7528u3055u308cu3001u305du306eu5f8cSambanovau30b2u30fcu30e0u30b3u30fcu30c9u751fu6210u30d4u30d7u30e9u30a4u30f3u3092u901au3055u308cu307eu3059u3002u30d5u30a1u30a4u30ebu51e6u7406u30d7u30edu30b2u30b9u306fu3001HTMLu30d5u30a1u30a4u30ebu3092u62bdu51fau3057u3066u4fddu5b58u3059u308bu305fu3081u306bu3001u524du8ff0u306eu3082u306eu3068u540cu69d8u3067u3059u3002
u81eau8eabu306eu30d2u30c7u30aau3067u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u4f7fu7528u3059u308bu306bu306fu3001u307eu305aTwelveLabs Playgroundu3092u4ecbu3057u3066u30a4u30f3u30c7u30c3u30afu30b9IDu3092u751fu6210u3057u3001u30d2u30c7u30aau3092u30a2u30c3u30d7u30edu30fcu30c9u3057u3066u30a4u30f3u30c7u30c3u30afu30b9u5316u3059u308bu3053u3068u3092u63a8u5968u3057u307eu3059u3002u305du308cu304cu5b8cu4e86u3057u305fu3089u3001u3053u3053u306bAPIu30adu30fcu3092u63a5u7d9au3057u3066u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu6a5fu80fdu3092u5145u5206u306bu6d3bu7528u3057u3066u304fu3060u3055u3044u3002
u6e96u5099u624bu9806
TwelveLabs Playgroundu304bu3089APIu30adu30fcu3092u53d6u5f97u3057u3001u74b0u5883u5909u6570u3092u8a2du5b9au3057u307eu3059u3002
TwelveLabs Playgroundu3092u4ecbu3057u3066pegasus-1.2u3092u9078u629eu3057u3001u30a4u30f3u30c7u30c3u30afu30b9u3092u4f5cu6210u3057u307eu3059u3002u305du3057u3066u3001u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u5c02u7528u306eindex_idu3092u53d6u5f97u3057u307eu3059u3002
GitHubu304bu3089u30d7u30edu30b8u30a7u30afu30c8u3092u30afu30edu30fcu30f3u3057u307eu3059u3002
SambaNovau30c0u30c3u30b7u30e5u30dcu30fcu30c9u304bu3089APIu30adu30fcu3092u53d6u5f97u3057u307eu3059u3002
TwelveLabsu3068SambaNovau306eu8aadu8a3cu60c5u5831u3092u542bu3080.envu30d5u30a1u30a4u30ebu3092u4f5cu6210u3057u307eu3059u3002
u3053u308cu3089u306eu624bu9806u304cu5b8cu4e86u3059u308bu3068u3001u958bu767au3092u59cbu3081u308bu6e96u5099u306eu6574u3044u307eu3059uff01
Video2Gameu30a2u30d7u30eau306eu89e3u8aac
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau306bu5909u63dbu3059u308bu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu69cbu7bc9u65b9u6cd5u306bu7126u70b9u3092u5f53u3066u307eu3059u3002u30a2u30d7u30eau306fu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bNext.jsu3001u30d0u30c3u30afu30a8u30f3u30c3u30c9u306bCORSu3092u6709u52b9u306bu3057u305fFlask APIu3092u4f7fu7528u3057u3066u3044u307eu3059u3002u3053u3053u3067u306fu3001Video2Gameu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4e2du6838u30d0u30c3u30afu30a8u30f3u30c3u30c9u30e6u30fcu30c6u30a3u30eau30c6u30a3u306eu5b9fu88c5u3068u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30bbu30c3u30c8u30a2u30c3u30d7u306bu7126u70b9u3092u5f53u3066u307eu3059u3002
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001SambaNovau3092u4ecbu3057u3066u30a2u30afu30bbu30b9u3059u308bu3053u3068u3067u3001u30b2u30fcu30e0u30b3u30fcu30c9u751fu6210u306bu9ad8u901fu63a8u8ad6LLMu3092u4f7fu7528u3059u308bu65b9u6cd5u306bu7126u70b9u3092u5f53u3066u307eu3059u3002u305du306eu30a2u30afu30bbu30b9u304cu3044u304bu306bu7c21u5358u304bu3092u898bu3066u307fu307eu3057u3083u3046u3002u8a73u7d30u306au30b3u30fcu30c9u69cbu9020u3068u30bbu30c3u30c8u30a2u30c3u30d7u6280u8853u306bu3064u3044u3066u306fu3001GitHubu306e README.md u3092u3054u78bau8a8du304fu3060u3055u3044u3002
1 - u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fTwelveLabsu306eu30d2u30c7u30aau304bu3085u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau3092u751fu6210u3059u308bu65b9u6cd5
1.1 u5fc5u898au306au8a2du5b9au3092u884cu3046
u3059u3079u306eu306eu5fc5u898au306au8a2du5b9au306f config.py u3067u5b9au7fa9u3055u308cu3001u74b0u5883u5909u6570u304bu3089u5024u304cu30edu30fcu30c9u3055u308cu307eu3059u3002u3053u306eu96c6u4e2du5316u3055u308cu305fu8a2du5b9au30a2u30d7u30edu30fcu30c1u306bu3088u308au3001u3059u3079u306eu5909u6570u306bu7c21u5358u306bu30a2u30afu30bbu30b9u3067u304du3001u7d20u6674u3089u3057u304fu6574u7406u3055u308cu7ba1u7406u3057u3084u3059u3044u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu30bbu30c3u30c8u30a2u30c3u30d7u3092u7dadu6301u3067u304du307eu3059u3002
backend/app/config.py (7-24 u884cu76ee)
class Config: ` # API credentials loaded from environment variables TWELVELABS_API_KEY = os.getenv("TWELVELABS_API_KEY") SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY") TWELVELABS_INDEX_ID = os.getenv("TWELVELABS_INDEX_ID") SAMBANOVA_BASE_URL=os.getenv("SAMBANOVA_BASE_URL") APP_URL = os.getenv("APP_URL", "http://localhost:8000") # Directory paths for file organization GAMES_DIR = "generated_games" # Directory to store generated game files CACHE_DIR = "game_cache" # Directory for caching game-related data INSTRUCTIONS_DIR = "instructions" # # Directory containing prompt files # SambaNova service configuration SAMBANOVA_BASE_URL = SAMBANOVA_BASE_URL SAMBANOVA_MODEL = "DeepSeek-V3-0324" # LLM text generation parameters GENERATION_TEMPERATURE = 0.1 GENERATION_TOP_P = 0.1 GENERATION_MAX_TOKENS = 16000 MIN_HTML_LENGTH = 7000
TwelveLabsu3068SambaNovau306eu8aadu8a3cu60c5u5831u3092u8a2du5b9au3057u305fu5f8cu3001INSTRUCTIONS_DIR u304cu521du671fu5316u3055u308cu307eu3059u3002u3053u306eu30c1u30ecu30afu30c8u30eau306bu306fu3001u30d7u30edu30b2u30b9u5168u4f53u3067u4f7fu7528u3055u308cu308bu3059u3079u306eu4e8eu5148u306bu5b9au7fa9u3055u308cu305fu30d7u30edu30f3u30d7u30c8u304cu542bu305eu308cu307eu3059u3002u751fu6210u3055u308cu305fu3059u3079u306eu53ccu65b9u5411u30b2u30fcu30e0u306f GAMES_DIR u306bu4fddu5b58u3055u308cu3001CACHE_DIR u306bu30adu30e3u30c3u30b7u30e5u3055u308cu307eu3059u3002
u30b3u30fcu30c9u751fu6210u306bu4f7fu7528u3055u308cu308bu30e2u30c7u30ebu306f DeepSeek-V3-0324 u3067u3042u308au3001u30e9u30f3u30c0u30e0u6027u3092u6e1bu3089u3059u305fu3081u306b 0.1 u306eu6e29u5ea6u304cu8a2du5b9au3055u308cu3001max_tokens u306eu5236u9650u304cu5b9au7fa9u3055u308cu3066u3044u307eu3059u3002u3057u8a66u3057u3066u307fu305fu3044u5834u5408u306fu3001u3053u308cu3089u306eu30d1u30e9u30e1u30fcu30bfu3092u5a09u66f4u3059u308bu304bu3001u8a2du5b9au5185u3067u5225u306eu30e2u30c7u30ebu306bu5207u308au66ffu3048u308bu3053u306eu304cu3067u304du307eu3059u3002
1.2 u30a4u30f3u30c7u30c3u30afu30b9u3092u53d6u5f97u3059u308b
u30e2u30fcu30b6u30fcu304cu30ddu30fcu30bfu30ebu3092u4ecbu3057u3066TwelveLabs APIu30adu30fcu3092u63a5u7d9au305bu308cu3070u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu305du308cu3092u4f7fu7528u3057u3066u30a2u30abu30a6u30f3u30c8u306bu95a2u9023u4ed8u3051u3089u308fu305fu3059u3079u306eu30a4u30f3u30c7u30c3u30afu30b9u3092u53d6u5f97u3057u307eu3059u3002u305du306eu5f8cu3001u30ecu30b9u30ddu30f3u30b9u304cu69cbu9020u5316u3055u308eu3001u8868u793au3059u308bu305fu3081u306bu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu9001u4fe1u3055u308cu307eu3059u00e3u3002
def get_indexes(self): try: print("Fetching indexes...") # Use direct HTTP request if not self.api_key: print("No API key available") return [] # To get the list of indexes url = "https://api.twelvelabs.io/v1.3/indexes" headers = { "accept": "application/json", "x-api-key": self.api_key } response = requests.get(url, headers=headers) if response.status_code == 200: data = response.json() result = [] # Structuring the relevant information needed for index in data.get('data', []): result.append({ "id": index['_id'], "name": index['index_name'] }) return result else: print(f"Failed to fetch indexes: Status {response.status_code}") return [] except Exception as e: print(f"Error fetching indexes: {e}") return []
1.3 u9078u629eu3055u308cu305f index_id u306bu5bfeu5fdcu3059u308bu30d2u30c7u30aau3092u53d6u5f97u3059u308b
u30e2u30fcu30b6u30fcu304cu30a4u30f3u30c7u30c3u30afu30b9u3092u9078u629eu3059u308bu3068u3001u5bfeu5fdcu3059u308b index_id u304cu30adu30e3u30d7u30c1u30e3u3055u308cu307eu3059u3002u53ccu65b9u5411u5b66u7fd2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u751fu6210u3059u308bu306bu306fu3001u305du306eu30a4u30f3u30c7u30c3u30afu30b9u304bu3089u7279u5b9au306eu30d2u30c7u30aau3092u9078u629eu3059u308bu3053u306eu304cu3042u308au307eu3059u3002u9078u629eu3055u308cu305f index_id u3092u4f7fu7528u3057u3066u3001u305du306eu30a4u30f3u30c7u30c3u30afu30b9u306bu95a2u9023u4ed8u3051u3089u308fu305fu3059u3079u306eu30d2u30c7u30aau3092u53d6u5f97u3059u308bu305fu3081u306bu3001u305du306eu30e1u30bdu30c3u30c9u304cu547cu3073u51fau3055u308cu307eu3059u3002
def get_videos(self, index_id): try: # Use direct HTTP request if not self.api_key: print("No API key available") return [] # List of Videos info of that respective index id url = f"https://api.twelvelabs.io/v1.3/indexes/{index_id}/videos" headers = { "accept": "application/json", "x-api-key": self.api_key } response = requests.get(url, headers=headers) if response.status_code == 200: data = response.json() result = [] for video in data.get('data', []): system_metadata = video.get('system_metadata', {}) # Structuring the response to get relevant information to showcase on the frontend result.append({ "id": video['_id'], "name": system_metadata.get('filename', f'Video {video["_id"]}'), "duration": system_metadata.get('duration', 0) }) return result else: print(f"Failed to fetch videos: Status {response.status_code}") return [] except Exception as e: print(f"Error fetching videos for index {index_id}: {e}") return []
u30d2u30c7u30aau3092u9078u629eu3059u308bu3068u3001video_id u304fu305du306eu30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u306eu305du306eu5f8cu306eu5206u6790u30d7u30edu30b2u30b9u306bu9001u4fe1u3055u308cu307eu3059u3002
1.4 pegasus-1.2 u3067u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u5206u6790u3059u308b
u30a2u30cau30e9u30a4u30bau30e6u30fcu30c6u30a3u30eau30c6u30a3u306eu76eeu7684u306fu3001u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u3057u3001u305du306eu30b3u30f3u30c6u30adu30b9u30c8u306bu57fau3065u3044u3066u6709u610fu7fa9u306eu3042u308bu6307u793au3092u751fu6210u3059u308bu3053u306eu3067u3059u3002u3053u308cu3089u306eu6307u793au306fu3001u53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u69cbu7bc9u3059u308bu305fu3081u306eu57fau790eu3068u306au308au3001u305du306eu5f8cu306eu30b3u30fcu30c9u751fu6210u30d7u30edu30b2u30b9u3092u5c0eu304du307eu200bu200bu3059u3002u3053u306eu5206u6790u306bu4f7fu7528u3055u308cu308bu30d7u30edu30f3u30d7u30c8u306fu3001u30d0u30c3u30afu30a8u30f3u30c3u30c9u3067u30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u3068u3057u3066u4e8eu514au306bu5b9au7fa9u3055u308cu3066u3044u307eu3059u3002u3053u3061u3089u3067u3001u5206u6790u30d7u30edu30f3u30d7u30c8 u304cu78bau8a8du3067u304eu307eu3059u3002
def analyze_video(self, video_id, prompt): try: # Send video analysis request to TwelveLabs API with custom prompt analysis_response = self.client.analyze( video_id=video_id, prompt=prompt ) return analysis_response.data except Exception as e: print(f"Error analyzing video {video_id}: {e}") raise e
video_id u3068u30d7u30edu30f3u30d7u30c8u306fu3001self.client.analyze u306bu30d1u30e9u30e1u30fcu30bfu3068u3057u3066u63d0u4f9bu3055u308cu3001u305du306eu30e1u30bdu30c3u30c9u304cu30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u30fbu5206u6790u3057u3066u6307u793au7d50u679cu3092u751fu6210u3057u307eu3059u3002
1.5 SambaNova u3092u4f7fu7528u3057u305fu53ccu65b9u5411u30b2u30fcu30e0u30b3u30fcu30c9u306eu751fu6210
u5206u6790u7d50u679cu3092u53d7u3051u53d6u308bu306fu3058u3081u308bu3068u3001u751fu6210u3055u308cu305fu30b3u30fcu30c9u30e6u30fcu30c6u30a3u30eau30c6u30a3u304cu200bu200bu30c8u30eau30acu30fcu3055u308cu307eu3059u3002u3053u306eu624bu9806u3067u306fu3001u514au306bu5b9au7fa9u3055u308cu305fu30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8u3068u3068u3082u306bu3001u5206u6790u51fau529bu304cu30e2u30fcu30b6u30fcu30d7u30edu30f3u30d7u30c8u3068u3057u3066u9001u3089u308cu307eu3059u3002u4f7fu7528u3055u308cu308bu30e2u30c7u30eb DeepSeek-V3-0324 u306fu3001u524du8ff0u306eu624bu98061.1u3067u8a2du5b9au3057u305fu3082u306eu3068u540cu3058u3067u3001u3059u3002
u3053u306e u30b7u30b9u30c6u30e0u30d7u30edu30f3u30d7u30c8 u306fu3001u51fau529bu306eu4e2du6838u306eu8981u4ef6u3068u671fu5f85u3055u308cu308bu69cbu9020u3092u69cbu60f3u3057u3001u30e2u30c7u30ebu304cu30bfu30b9u30afu306eu76eeu7684u3068u5236u7d04u3092u7406u89e3u3057u3066u3044u308bu3053u306eu3092u78bau4fddu3057u307eu3059u3002u4e00u65b9u3067u3001u30e2u30fcu30b6u30fcu30d7u30edu30f3u30d7u30c8 u306fu3001u5206u6790u7d50u679cu306bu52a0u3048u3001u30ecu30a4u30a2u30a6u30c8u3001u30c7u30b6u30a4u30f3u3001u914du8272u3001u30d5u30a9u30fcu30deu30c3u30c8u306bu95a2u3059u308bu8a73u7d30u306au8ffdu52a0u6307u793au3092u7d44u307fu8fbcu3093u3067u3044u307eu3059u3002u3053u308cu3089u306eu30d7u30edu30f3u30d7u30c8u304cu5fc5u898au306bu5fdcu3058u3066u3001u30e2u30c7u30ebu3092u30acu30a4u30c9u3057u3066u3001u7126u70b9u304cu7d5eu3089u308cu305fu6574u7406u3055u308cu305fu53ccu65b9u5411u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u751fu6210u3057u307eu3059u3002
def generate_game_stream(self, system_prompt, user_prompt): print("Starting streaming generation...") if not self._test_api_connection(): yield "Error: Sambanova API is not reachable" return try: start_time = time.time() response = self.client.chat.completions.create( model=current_app.config['SAMBANOVA_MODEL'], messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt} ], temperature=current_app.config['GENERATION_TEMPERATURE'], top_p=current_app.config['GENERATION_TOP_P'], max_tokens=current_app.config['GENERATION_MAX_TOKENS'], stream=True ) print(f"API call initiated in {time.time() - start_time:.2f}s") chunk_count = 0 total_content = "" last_chunk_time = time.time() for chunk in response: current_time = time.time() if current_time - last_chunk_time > 30: # 30 second timeout print(f"No chunk received for 30 seconds, breaking...") break delta = getattr(chunk.choices[0], 'delta', None) content = getattr(delta, 'content', '') if delta else '' if content: chunk_count += 1 total_content += content last_chunk_time = current_time # Print live streaming progress if chunk_count % 20 == 0: # Print every 20 chunks print(f"Stream: {chunk_count} chunks, {len(total_content)} chars") yield content print(f"Streaming completed: {chunk_count} chunks, {len(total_content)} total chars") print(f"Total streaming time: {time.time() - start_time:.2f}s") except Exception as e: error_msg = f"Streaming error: {str(e)}" print(error_msg) print(f"Error type: {type(e).__name__}") if hasattr(e, 'response'): print(f"Response status: {e.response.status_code}") print(f"Response text: {e.response.text}") yield error_msg
SambaNova u306e API u3092 stream=True u3067u547cu3073u51fau3059u3068u3001u751fu6210u3055u308cu305fu30b3u30f3u30c6u30f3u30c4u306fu4f5cu6210 u3055u308cu305fu9806u306bu5206u5272u3055u308cu3066u9001u308au8fd4u3055u308cu3001u3053u306eu95a2u6570u304cu305du308cu3092u3059u3050u306bu30e2u30fcu30b6u30fcu306bu8ff4u3057u307eu3059u3002u898bu4e8bu306au306eu306fu3001u5185u8535u3055u308cu305fu5b89u5168u5b9au4fddu6a5fu69cbu3067u3059u3002u30deu30c3u30c1u30f3u30b0u306eu7121u99c4u306au547cu3073u51fau3059u3092u907fu3051u308bu305fu3081u306bu3001u307eu305a API u63a5u7d9au3092u30c6u30b9u30c8u3057u3001u8a70u307eu3063u305fu63a5u7d9au3092u635eu3046u305fu3081u306b 30 u79d2u306eu30bfu30a4u30e0u30a2u30a6u30c8u3092u5b9fu88c5u3057u300120 u30c1u30e3u30f3u30afu3054u3068u306bu8a73u7d30u306au30e1u30c8u30eau30afu30b9u3092u8a18u9332u3059u308bu305fu3081u3001u30d1u30d5u30a9u30fcu30deu30f3u30b9u3092u30eau30a2u30ebu30bfu30a4u30e0u3067u76e3u8996u3067u3042u308au307eu3059u00e3u3002
1.6 u751fu6210u306eu305fu3081u306eu95a2u6570u547cu3073u51fau3057u30d4u30d7u30e9u30a4u30f3
u3053u306eu30bbu30afu30b7u30e7u30f3u3067u306fu3001u524du8ff0u306eu30e2u30fcu30c6u30a3u30eau30c6u30a3u95a2u6570u304cu547cu3073u51fau3055u308cu5b9fu884cu3055u308cu308bu3001u30d7u30edu30b2u30b9u306eu5168u4f53u30d4u30d7u30e9u30a4u30f3u306bu3064u3044u3066u8aacu660eu3057u307eu3059u3002u3053u308cu306fu3001u5206u6790u306bu5fc5u898au306a video_id u3068u95a2u9023u4ed8u3051u3089u308fu305f API u30adu30fcu306eu5b58u5728u3092u691cu8a3cu3059u308bu3053u306eu304bu3089u59cbu307eu308au307eu3059u3002u78bau8a8du3055u308cu308bu306fu3058u3081u308bu3068u3001u5206u6790u30d7u30edu30f3u30d7u30c8u304fu304cu30ddu30fcu30c9u3055u308cu3001analyze_video u30aau30fcu30c6u30a3u30eau30c6u30a3u304cu30aau30eau30acu30fcu3055u308cu3066u6307u793au7d50u679cu3092u751fu6210u3057u307eu3059u3002u305du306eu5f8cu3001SambaNova u30b7u30b9u30c6u30e0 u30d7u30edu30f3u30d7u30c8u304cu30ddu30fcu30c9u3055u308cu3001u30b3u30fcu30c9u751fu6210 u30d7u30edu30b2u30b9u3092 u958bu59cbu3059u308bu30bfu30e1u306bu4f7fu7528u3055u308cu307eu3059u3002SambaNova u304bu3089u306eu7d50u679cu306fu30c1u30e3u30f3u30afu3054u3068u306bu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu30b9u30c8u30eau30fcu30dfu30f3u30b0u3055u308cu3001u30e2u30fcu30b6u30fcu306fu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30e9u30a4u30d6u751fu6210u3092u898bu308bu3053u306eu304cu3067u304du307eu3059u3002
u751fu6210u304fu5b8cu4e86u3057u30b9u30c8u30eau30fcu30dfu30f3u30b0 u304cu7d42u308fu308bu3068u3001u30e6u30fcu30c6u30a3u30eau30c6u30a3 u95a2u6570 file_service.process_html_content u304cu30ecu30b9u30ddu30f3u30b9u304bu3089 HTML u30b3u30f3u30c6u30f3u30c4 u3092u62bdu51fau3057u307eu3059u3002u3053u306eu62bdu51fau3055u308cu305f HTML u306fu3001file_service.save_html_file u3092u4f7fu7528u3057u3066u5225u30d5u30a1u30a4u30ebu3068u3057u3066u4fddu5b58u3055u308cu307eu3059u3002u4fddu5b58u3055u308cu305f HTML u30d1u30b9u3068u3068u3082u306bu3001video_idu3001video_analysisu3001u304au3088u3073u95a2u9023u3059u308bu30e1u30bf u30c7u30fcu30bfu306au3069u306eu4ed6u306eu95a2u9023u3059u308bu8a73u7d30u306fu3001u5f8cu3067u7c21u5358u306bu53d6u5f97 u3067u304du308bu3088u3046u306bu7d71u4e00u3055u308cu305f JSON u30d5u30a1u30a4u30ebu306b u683cu7d0du3055u308cu307eu3059u3002
@api_bp.route('/twelvelabs/regenerate', methods=['POST', 'GET']) @handle_errors def twelvelabs_regenerate(): from app.services.sample_games_service import SampleGamesService from app.services.twelvelabs_service import TwelveLabsService from app.services.sambanova_service import SambanovaService from app.services.file_service import FileService def event_stream(video_id, api_key): # Initialize service for managing generated games, consisting the loading the file handling sample_games_service = SampleGamesService() # Validate required parameters before processing if not video_id: yield f"event: error\ndata: video_id is required\n\n" return if not api_key: yield f"event: error\ndata: API key is required\n\n" return try: # Step 1 - Analyze video content using TwelveLabs yield f"event: progress\ndata: Starting analysis with TwelveLabs...\n\n" # Initialize TwelveLabs service with provided API key twelvelabs_service = TwelveLabsService(api_key=api_key) # Get analysis prompt template and analyze the video analysis_prompt = current_app.prompt_service.get_prompt('analysis') video_analysis = twelvelabs_service.analyze_video(video_id, analysis_prompt) yield f"event: analysis\ndata: {video_analysis}\n\n" # Step 2 - Generate game code using SambaNova AI yield f"event: progress\ndata: Generating game with SambaNova...\n\n" sambanova_service = SambanovaService() # Prepare prompts for game generation using video analysis game_generation_prompt = current_app.prompt_service.get_prompt('game_generation', video_analysis=video_analysis) system_prompt = current_app.prompt_service.get_prompt('system') try: # Stream game generation in real-time chunks streamed_html = "" # Process each chunk of generated content as it arrives for chunk in sambanova_service.generate_game_stream(system_prompt, game_generation_prompt): if chunk: streamed_html += chunk # Send each chunk to client for real-time display yield f"event: game_chunk\ndata: {chunk}\n\n" # Step 3 - Save and process the complete generated game if streamed_html: # Process and clean up the generated HTML content file_service = FileService() html_content = file_service.process_html_content(streamed_html) # Save HTML file to disk with video ID as identifier html_file_path = file_service.save_html_file(html_content, video_id) # Create game metadata and save to file storage game_data = sample_games_service.create_game_data( video_id, video_analysis, html_file_path, twelvelabs_video_ids=[video_id], youtube_url='', video_title=f'TwelveLabs Video {video_id}', channel_name='TwelveLabs', view_count='Generated' ) sample_games_service.save_game(game_data) else: # No content was generated - report error to client yield f"event: error\ndata: No game content was generated\n\n" return except Exception as e: print(f"Error in SambaNova streaming: {str(e)}") yield f"event: error\ndata: Error streaming from SambaNova: {str(e)}\n\n" return yield f"event: done\ndata: [DONE]\n\n" except Exception as e: print(f"Error in TwelveLabs processing: {str(e)}") yield f"event: error\ndata: Error processing TwelveLabs video: {str(e)}\n\n" # Handle different HTTP methods for parameter extraction if request.method == 'GET': video_id = request.args.get('video_id') api_key = request.args.get('api_key') else: data = request.get_json() video_id = data.get('video_id') api_key = request.headers.get('X-Twelvelabs-Api-Key') if not video_id: return jsonify({"error": "video_id is required"}), 400 return Response(stream_with_context(event_stream(video_id, api_key)), mimetype='text/event-stream')
u751fu6210u30d7u30edu30b2u30b9 u304cu5b8cu4e86u3057 u30c1u30a7u30f3u30afu51e6u7406u304c u305du308cu305eu308cu7d42u308fu308bu3068u3001u751fu6210u3055u308cu305fu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3 u3068u305du306e u30b3u30fcu30c9u306f u4fddu5b58u3055u308cu305f JSON u304bu3089 u30edu30fcu30c9u3055u308cu3001u30ddu30fcu30bfu30eb u4e0au306bu30ecu30f3u30c0u30eau30f3u30b0u3055u308cu307eu3059u3002
2 - YouTubeURLu3092u4ecbu3057u3066u751fu6210u3059u308bu30bfu30e1u306eu95a2u6570u547cu3073u51fau3057u30d4u30d7u30e9u30a4u30f3
u30a4u30f3u30bfu30e9u30afu30c6u30a3u30d6u306au5b66u7fd2u30a2u30d7u30eau3092u751fu6210u3059u308bu30bfu30e1u306b YouTube u306e URL u3092u4f7fu7528u3059u308bu3084u3046u306au4ee3u66ffu624bu6bb5u3067u3082u3001u5168u4f53u306eu30d4u30d7u30e9u30a4u30f3u306fu307bu3068u3093u3069u540cu3058u3067u3059u3002u4e3bu306au9055u3044u306fu521du671fu306eu624bu9806u306bu3042u308au307eu3059u3002u30d2u30c7u30aau306fu307eu305a u51e6u7406u3055u308c u30edu30fcu30abu30eb u307eu305fu306f u30b5u30fcu30d0u30fc u306b u4fddu5b58u3055u308cu3001u305du306eu5f8c TwelveLabs API u3092u4f7fu7528u3057u3066 u30a4u30f3u30c7u30c3u30afu30b9u5316 u3055u308cu307eu3059u3002u30b5u30ddu30fcu30c8u3055u308cu3066u3044u308b u30d7u30e9u30c3u30c8u30d5u30a9u30fcu30e0 URL u304bu3089 u30d2u30c7u30aau306e u30c0u30a6u30f3u30edu30fcu30c9u3092 u51e6u7406u3059u308b u30e6u30fcu30c6u30a3u30eau30c6u30a3u3092 u7d44u307fu8fbcu3080 u3053u306eu304fu3001u305du306eu5f8c u30a4u30f3u30c7u30c3u30afu30b9u5316u306e u5fc5u898au306a u624bu9806 u304cu8a2du5b9au3055u308b u3053u306eu304cu3042u308au307eu3059u3002
u30a4u30f3u30c7u30c3u30afu30b9u5316u304cu3069u306eu3088u3046u306bu884cu308fu308cu308bu304bu3092u7406u89e3u3059u308bu306bu306fu3001u4ee5u4e0bu306eu30b3u30fcu30c9u30b9u30cbu30c3u30dau30c3u30c8u3092u53c2u7167u3057u3066u304fu3060u3055u3044u3002
def _index_video_file(self, file_path, index_id): try: # Create a new indexing task for the video file task = self.twelvelabs_service.client.task.create( index_id=index_id, file=file_path, ) print(f"Indexing task created: {task.id}") max_wait_time = 900 start_time = time.time() while time.time() - start_time < max_wait_time: task = self.twelvelabs_service.client.task.retrieve(task.id) # Handle different task status outcomes if task.status == "ready": print(f"Indexing completed successfully. Video ID: {task.video_id}") # Indexing completed successfully - video is now searchable/analyzable return task.video_id elif task.status == "failed": print(f"Indexing failed: {task.status}") return None elif task.status in ["processing", "pending"]: elapsed = int(time.time() - start_time) print(f"Indexing in progress... Status: {task.status} (Elapsed: {elapsed}s)") time.sleep(15) else: print(f"Unknown status: {task.status}") time.sleep(10) print("Indexing timed out") return None except Exception as e: print(f"Error during video indexing: {str(e)}") return None
YouTube URL u304bu3089 u53ccu65b9u5411u30a2u30d7u30ea u751fu6210u307eu3067u306e u5b8cu5168u306a u30d7u30edu30b2u30b9 u30d4u30d7u30e9u30a4u30f3u306fu3001u3053u3061u3089u3067 u78bau8a8du3067u304du307eu3059u3002
YouTube URL u30d2u30c7u30aa u5411u3051u306e u518du751fu6210 u6a5fu80fdu306fu3001u30d2u30c7u30aau304c u3059u3067u306b u30a4u30f3u30c7u30c3u30afu30b9u5316 u3055u308cu3001u518du5206u6790 u3084 u518du751fu6210 u306e u6e96u5099u304c u6574u3063u3066u3044u308b u305fu3081u3001u524du8ff0u306e u3082u306eu3068 u5168u304f u540cu3058 u3088u3046u306b u52d5u4f5cu3057u307eu3059u3002
u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u306eu89e3u8aac u3092 u6df1u3081u308b u306eu306b u5f79u7acbu3061u3001u30d2u30c7u30aau3092 u4f53u9a13 u3057 u30a4u30f3u30bfu30e9u30afu30c8 u3057 u5b66u3073 u904au3076u3001 u307eu3063u305fu304f u65b0u3057u3044 u65b9u6cd5 u3092 u63d0u4f9bu3059u308b u30ddu30fcu30c3u30eb u306e u6a5fu80fdu3092 u30b9u30b0 u306b u78bau8a8du3057u307eu3057u3087u3046u3002

u30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u8a66u3059u30bfu30e1u306e u3055u3089u306au308b u30a2u30a4u30c7u30a2
u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u304cu3069u306eu3088u3046u306b u53ccu65b9u5411u306e u4f53u9a13u306b u5909u308fu308bu304b u3092u7406u89e3u3059u308b u3053u306eu306fu3001u3088u308a u9b45u529bu7684u306eu3001 u305du3057u3066 u5fc5u898au306bu5fdcu3058u305f u5b66u7fd2u306e u9053u3092 u958bu304du307eu3059u3002u30a2u30cau30e9u30a4u30ba u30a8u30f3u30b8u30f3 u3068 Sambanova u3092 u4f7fu3063u3066 u8a66u3059u3053u306eu304cu3067u304du308b u5b9fu9a13u7684u306a u65b9u5411 u306fu3001u4ee5u4e0bu306eu901au308a u3067u3059uff1a
ud83cudfae u30d5u30a3u30fcu30c9u30d0u30c3u30af u30ebu30fcu30d7 u306bu3088u308b u9ad8u901fu306a u30a4u30c6u30ecu30fcu30b7u30e7u30f3 u2014 SambaNovau3092 u6d3bu7528u3057u305f u30b2u30fcu30e0u30b3u30fcu30c9u751fu6210u30ebu30fcu30d7u306bu3001u30e2u30fcu30b6u30fc u30d5u30a3u30fcu30c9u30d0u30c3u30af u3092 u76f4u63a5 u7d44u307fu8fbcu307fu307eu3059u3002 u3000
ud83dudd0d u6df1u3044 u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u306e u7814u7a76 u2014 u9ad8u901fu63a8u8ad6u30e2u30c7u30ebu3092 u4f7fu3063u3066 u30d2u30c7u30aa u5206u6790 u306e u8a73u7d30u306a u89e3u8aac u3092u884cu3044u307eu3059u3002u4e3bu306a u610fu898b u3092 u81eau52d5u7684u306b u62bdu51fau3057u3001u53c2u7167 u3092 u7279u5b9au3057u3001u95a2u9023u3059u308b u5f15u7528 u3084 u5916u90e8u306e u5b66u7fd2u8cc7u6599 u3092 u660eu3089u304bu306b u3057u307eu3059u3002
ud83eudde0 u30d2u30c7u30aa Agentic AI u2014 u30a8u30fcu30b8u30a7u30f3u30c8u30d4u30d7u30e9u30a4u30f3 u306e u4e00u90e8u3068u3057u3066 u63a8u8ad6u30d9u30fcu30b9 u306e u63a8u8ad6u30e2u30c7u30ebu3092 u7d45u5408 u3057u307eu3059u3002u3053u308cu306bu3088u308au3001 u30b7u30b9u30c6u30e0 u306fu30d2u30c7u30aau7de8u96c6u306e u5909u63db u306bu5fc5u898au306a u8a08u753b u3092 u7acbu3066u3001u8abfu6574u3057u3001 u9069u5207u306a u30c4u30fcu30eb u3092 u4f7fu3046 u3053u306eu304cu3067u304du307eu3059u3002
u304au308fu308au306b
u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu306fu3001u30d2u30c7u30aau7406u89e3u304cu3001 u79c1u305fu3061 u304cu5b66u3073 u30d2u30c7u30aa u30b3u30f3u30c6u30f3u30c4 u3068 u30a4u30f3u30bfu30e9u30afu30c8 u3059u308b u65b9u6cd5 u3092u3001 u3069u306eu3088u3046u306b u518du5b9au7fa9 u3067u304du308b u304bu3092 u63a2u308a u307eu3059u3002 u30d2u30c7u30aa u5206u6790 u751fu6210u306e u305fu3081u306b TwelveLabs u3092u3001u305du3057u3066 u9ad8u301fu306a u30b3u30fcu30c9u30d9u30fcu30b9 u30b2u30fcu30e0 u751fu6210 u306e u305fu3081u306b SambaNova u3092 u7d44u307fu5408u308fu305bu308b u3053u306eu3067u3001 u53d7u52d5u7684u306e u6559u80b2u30d2u30c7u30aau3092 u53ccu65b9u5411u306e u30b2u30fcu30e0u578b u5b66u7fd2 u4f53u9a13 u306b u5909u3048u308b u30b7u30b9u30c6u30e0 u3092 u69cbu7bc9 u3057u307eu3057u305fu3002Video2Game u306fu3001 u30deu30ebu30c1u30e2u30fcu30c0u30ebu89e3 u3068u3001 u904au3073 u5fc3 u306e u3042u308b u5b66u3073u3001u30e0 u3092 u7d39u4ecbu3057 u53ccu65b9u306e u67b6u3051u6a4b u3068u306au308bu3053u3068u3067u3001 u5f93u6765u306e u30d2u30c7u30aa u518du751f u3092 u8d85u3048u305f u6c89u6d78 u578b u306e u500bu4ebau5316 u3055u308cu305f u6559u80b2 u3092u63d0u4f9bu3057u307eu3059u3002
u8ffdu52a0u306eu30eau30bdu30fcu30b9
u30d2u30c7u30aa u5206u6790 u30a8u30f3u30b8u30f3 Pegasus-1.2 u306bu3064u3044u3066u3001 u3088u308a u8a73u3057u304f u5b66u3073 u307eu3057u3087u3046u3002TwelveLabs u3092 u3055u3089u306b u63a2u308au3001 u30d2u30c7u30aau30b3u30f3u30c6u30f3u30c4 u5206u6790 u306e u7406u89e3u3092 u6df1u3081u308b u30bfu30e1u306bu3001 u3053u308cu3089u306e u30c4u30fcu30eb u3092 u78bau8a8d u3057u3066 u304fu3060u3055u3044uff1a
u3055u3089u306au308b u30e6u30fcu30b9 u30b1u30fcu30b9 u306e u63a2u7d22uff1a SambaNova u30e2u30c7u30eb u30cfu30d6u3092 u8a2au308cu3066u3001 u3055u307eu3056u307eu306a u30e2u30c7u30eb u3068 u30d3u30b8u30cdu30b9 u306e u5ea7u6a19 u306b u5408u308fu305bu305f u985eu4f3cu306e u30efu30fcu30afu30d5u30edu30fcu3092 u3069u306eu3088u3046u306b u5b9fu88c5 u3059u308b u304b u3092 u5b66u3092u307fu3001u63a2u3063u3066u307f u307eu3057u3087u3046u3002
u8a71u3057 u5408u3044u306b u53c2u52a0u3059u308buff1a u3053u306e u7d45u5408 u306b u5c0du3059u308b u30d5u30a3u30fcu30c9u30d0u30c3u30af u3092 TwelveLabs Discordu3067 u5171u6709u3057 u307eu3057u3087u3046u3002
u30c1u30e5u30fcu30c8u30eau30a2u30eb u3092 u63a2u308buff1a u5b8cu5168u306a u30c1u30e5u30fcu30c8u30eau30a2u30eb u3067u3001 TwelveLabs u306e u529b u3092 u3055u3089u306b u6df1u304f u5b66u3073 u307eu3057u3087u3046u3002
u3053u308cu3089u306e u30eau30bdu30fcu30b9 u3092 u4f7fu3063u3066 u77e5u8b5a u3092 u3072u308du3052u3001 TwelveLabs u306e u30d2u30c7u30aau7406u89e3u6280u8853 u3092 u4f7fu3063u305f u9769u65b0u306e u30a2u30d7u30ea u3092 u4f5cu308b u3053u306eu3092 u5fdcu63f4u3057 u307eu3059u3002





