├── .browserslistrc ├── .editorconfig ├── .eslintrc.cjs ├── .gitignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.ja_JP.md ├── README.md ├── README.zh_CN.md ├── app.config.ts ├── app.vue ├── assets └── css │ └── main.css ├── components ├── AppNav.vue ├── AppSidebar.vue ├── AppVideoFeed.vue ├── LangTheme.vue ├── LocLink.vue ├── Logo.vue ├── SiteFooterSection.vue ├── SiteNav.vue ├── Social.vue └── content │ └── Resources.vue ├── composables └── states.ts ├── content ├── en-US │ └── app │ │ └── docs.md ├── ja-JP │ └── app │ │ └── docs.md └── zh-CN │ └── app │ └── docs.md ├── error.vue ├── i18n.config.ts ├── lang ├── en-US.ts ├── ja-JP.ts └── zh-CN.ts ├── layouts ├── application.vue └── default.vue ├── nuxt.config.ts ├── package.json ├── pages ├── app │ ├── Community-Feed.vue │ ├── Help.vue │ ├── Personal-Feed.vue │ ├── Video-Generation.vue │ ├── docs │ │ └── [...slug].vue │ └── index.vue ├── cookie-policy.vue ├── dmca.vue ├── index.vue ├── legal-notice.vue └── terms-of-service.vue ├── pnpm-lock.yaml ├── public ├── 404.svg ├── 500.svg ├── alipay.jpg ├── bg.webp ├── favicon.ico ├── fonts │ ├── PlusJakartaSans-Bold.woff2 │ ├── PlusJakartaSans-BoldItalic.woff2 │ ├── PlusJakartaSans-ExtraBold.woff2 │ ├── PlusJakartaSans-ExtraBoldItalic.woff2 │ ├── PlusJakartaSans-ExtraLight.woff2 │ ├── PlusJakartaSans-ExtraLightItalic.woff2 │ ├── PlusJakartaSans-Italic.woff2 │ ├── PlusJakartaSans-Italic[wght].woff2 │ ├── PlusJakartaSans-Light.woff2 │ ├── PlusJakartaSans-LightItalic.woff2 │ ├── PlusJakartaSans-Medium.woff2 │ ├── PlusJakartaSans-MediumItalic.woff2 │ ├── PlusJakartaSans-Regular.woff2 │ ├── PlusJakartaSans-SemiBold.woff2 │ ├── PlusJakartaSans-SemiBoldItalic.woff2 │ └── PlusJakartaSans[wght].woff2 ├── logo.svg ├── logo.webp ├── maintenance.svg ├── openai.svg ├── profile.webp ├── robots.txt ├── sitemap.xml ├── vercel.png └── wechat.jpg ├── server ├── api │ └── videos │ │ ├── generation.post.ts │ │ └── index.get.ts ├── data │ └── sora_videos.json ├── models │ └── Video.ts ├── routes │ ├── fakeOpenAISoraAPI.post.ts │ └── v1 │ │ └── [...].ts ├── services │ └── videoService.ts └── tsconfig.json ├── tailwind.config.js ├── tsconfig.json └── utils ├── index.ts ├── lang.ts ├── theme.js └── title.ts /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | not ie 11 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue,html,css,md}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['@nuxt/eslint-config'], 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | *.bak -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | src/assets 3 | public 4 | dist 5 | ops 6 | src/plugins -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "tabWidth": 2, 5 | "printWidth": 300, 6 | "arrowParens": "avoid" 7 | } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | # SwiftSora Open Source License 2 | 3 | The SwiftSora is licensed under the Apache License 2.0, with the following additional conditions: 4 | 5 | 1. SwiftSora is permitted to be used for commercialization. You can use SwiftSora as a "backend-as-a-service" for your other applications, or delivering it to enterprises as an application development platform. However, when the following conditions are met, you must contact the producer to obtain a commercial license: 6 | 7 | a. Multi-tenant SaaS service: Unless explicitly authorized by SwiftSora in writing, you may not use the SwiftSora.AI source code to operate a multi-tenant SaaS service that is similar to the SwiftSora. 8 | b. LOGO and copyright information: In the process of using SwiftSora, you may not remove or moSwiftSora the LOGO or copyright information in the SwiftSora console. 9 | 10 | Please contact jasonwang188@gmail.com by email to inquire about licensing matters. 11 | 12 | 2. As a contributor, you should agree that your contributed code: 13 | 14 | a. The producer can adjust the open-source agreement to be more strict or relaxed. 15 | b. Can be used for commercial purposes, such as SwiftSora's cloud business. 16 | 17 | Apart from this, all other rights and restrictions follow the Apache License 2.0. If you need more detailed information, you can refer to the full version of Apache License 2.0. 18 | 19 | The interactive design of this product is protected by appearance patent. 20 | 21 | © 2024 SwiftSora. 22 | 23 | 24 | The SwiftSora software is licensed under the Apache License 2.0, with additional conditions outlined below: 25 | 26 | 1. **Commercial Usage:** SwiftSora is allowed for commercialization purposes. It can serve as a "fullstack-service" or "backend-as-a-service" for your applications or be provided to enterprises as an application development platform. However, under specific conditions, you must contact the producer for a commercial license: 27 | 28 | a. **Multi-tenant SaaS Service:** Without explicit written authorization from SwiftSora, you may not utilize the SwiftSora.AI source code to operate a multi-tenant SaaS service similar to SwiftSora. 29 | 30 | b. **LOGO and Copyright Information:** While using SwiftSora, you must not remove or modify the LOGO or copyright information in the SwiftSora console. 31 | 32 | For licensing inquiries, please contact jasonwang188@gmail.com via email. 33 | 34 | 2. **Contributor Agreement:** Contributors must agree that their contributed code: 35 | 36 | a. **Adjustment of Open-Source Agreement:** The producer has the authority to modify the open-source agreement to be more stringent or lenient. 37 | 38 | b. **Commercial Usage:** The contributed code can be used for commercial purposes, including SwiftSora's cloud business. 39 | 40 | All other rights and restrictions align with the Apache License 2.0. For more detailed information, refer to the full version of Apache License 2.0. 41 | 42 | The interactive design of this product is protected by an appearance patent. 43 | 44 | © 2024 SwiftSora. 45 | 46 | --- 47 | 48 | Licensed under the Apache License, Version 2.0 (the "License"); 49 | you may not use this file except in compliance with the License. 50 | You may obtain a copy of the License at 51 | 52 | http://www.apache.org/licenses/LICENSE-2.0 53 | 54 | Unless required by applicable law or agreed to in writing, software 55 | distributed under the License is distributed on an "AS IS" BASIS, 56 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | See the License for the specific language governing permissions and 58 | limitations under the License. -------------------------------------------------------------------------------- /README.ja_JP.md: -------------------------------------------------------------------------------- 1 | # SwiftSora - AIビデオジェネレーター 2 | 3 |
4 | SwiftSora 5 |
6 | 7 | オンラインデモはこちら 👉🏻👉🏻 [SwiftSora](https://www.swiftsora.com) 8 | 9 | SwiftSoraはOpenAI Soraモデルを基にしたオープンソースのAIビデオジェネレーターで、Nuxt 3、Vue 3、およびTailwind CSSを組み合わせたフルスタック開発技術を採用しています。これにはフレンドリーなWeb UIが含まれ、VercelやNetlifyなどのプラットフォームに数分で簡単にインストールできます。 10 | 11 | [![ウェブサイトデモ](https://img.shields.io/badge/Website-Demo-8A2BE2)](https://www.swiftsora.com) 12 | 13 | ![Stars](https://img.shields.io/github/stars/jasonwang178/swiftsora) ![Forks](https://img.shields.io/github/forks/jasonwang178/swiftsora) 14 | 15 | [English](https://github.com/jasonwang178/SwiftSora/blob/main/README.md) | [简体中文](https://github.com/jasonwang178/SwiftSora/blob/main/README.zh_CN.md) | [日本語](https://github.com/jasonwang178/SwiftSora/blob/main/README.ja_JP.md) 16 | 17 | ## 製品計画 18 | 19 | - [x] Web UI + サーバー 20 | - [ ] SSO - Google、Githubなど - 進行中 21 | - [ ] 国際化 - 進行中 22 | - [x] 英語 23 | - [x] 簡体中文 24 | - [ ] 繁体中文 25 | - [x] 日本語 26 | - [ ] Español 27 | - [ ] 한국어 28 | - [ ] 料金設定と支払い 29 | - [ ] Stripe支払い 30 | - デプロイ 31 | - [x] Vercel 32 | - [x] Netlify 33 | - [ ] Docker 34 | - セキュリティ 35 | - [x] OpenAI APIプロキシ 36 | - API接続 37 | - [ ] OpenAIのSora API統合(OpenAI Sora APIのリリースを待っています) 38 | 39 | ## デプロイ 40 | 41 | > [!注意] 42 | > このプロジェクトは実験的です。最適化されていますが、注意して使用することをお勧めします。リスクを自己負担し、潜在的な結果に注意してください。 43 | 44 | ### Vercel 45 | 46 | 推奨されるデプロイオプションはVercelですが、他のプラットフォームでも柔軟に選択できます。 47 | 48 | [![Vercelでデプロイ](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/jasonwang178/SwiftSora) 49 | 50 | - フレームワークのプリセットとしてNuxt.jsを選択 51 | - 以下の環境変数を追加: 52 | 53 | ```shell 54 | # あなたの実際のOPENAI_API_KEY 55 | OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxx 56 | 57 | # Soraモデルの名前を指定します。https://platform.openai.com/docs/api-referenceを確認してください 58 | OPENAI_API_MODEL=sora-1.0 59 | 60 | # 実際のOpenAI APIベースURLまたはOpenAI APIプロキシURLを設定します 61 | # 例: https://api.openai.com, https://api.myopenaiproxy.com 62 | OPENAI_API_BASE_URL=http://localhost:3000 63 | 64 | # このプロジェクトをデプロイしたときのホストまたはドメインのアドレスを使用します 65 | # 例: https://www.swiftsora.com/ 66 | OPENAI_API_PROXY_URL=http://localhost:3000 67 | ``` 68 | 69 | Vercelデプロイガイド 70 | 71 | Vercel Nuxtデプロイガイドを読む 👉🏻👉🏻 [こちら](https://vercel.com/docs/frameworks/nuxt)。 72 | 73 | ### Netlify 74 | 75 | Netlifyを使用してもデプロイできます。 76 | 77 | [![Netlifyにデプロイ](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/jasonwang178/SwiftSora) 78 | 79 | Netlify Nuxtデプロイガイドを読む 👉🏻👉🏻 [こちら](https://docs.netlify.com/integrations/frameworks/nuxt/)。 80 | 81 | ### 他のプラットフォーム 82 | 83 | Node.js v18+がインストールされていることを確認してください。 84 | 85 | メインフォルダに`.env`ファイルを追加します。[こちら](https://github.com/jasonwang178/SwiftSora?tab=readme-ov-file#vercel)の説明に従って値を設定します。 86 | 87 | - `OPENAI_API_PROXY_URL`の値をデプロイしたURLで置き換えてください。たとえば、プロジェクトを にデプロイした場合、`OPENAI_API_PROXY_URL`を に更新します。 88 | - `OPENAI_API_BASE_URL`を一時的にデプロイURLに調整します。一旦OpenAI Sora APIが利用可能になると、それを`https://api.openai.com`または他のOpenAIプロキシURLに更新してください。 89 | 90 | 本番環境にアプリケーションを構築する: 91 | 92 | ```bash 93 | # npm 94 | npm run build 95 | 96 | # pnpm 97 | pnpm run build 98 | 99 | # yarn 100 | yarn build 101 | 102 | # bun 103 | bun run build 104 | ``` 105 | 106 | [Nuxt.jsデプロイドキュメント](https://nuxt.com/docs/getting-started/deployment)を参照して、詳細情報を入手してください。 107 | 108 | ## 紹介 109 | 110 | ### SwiftSoraについて [#]{.h-link} 111 | 112 | SwiftSoraは、オープンソースのAIビデオジェネレーターで、Nuxt、Vue 3、およびTailwind CSSを組み合わせたフルスタック開発技術を採用しています。前後端プログラムを含み、ユーザーフレンドリーなWeb UIを備え、VercelやNetlifyなどのプラットフォームに簡単にインストールできます。 113 | 114 | OpenAIのSoraモデルを使用することで、ユーザーはテキストをビデオに変換でき、このプラットフォームはビデオ作成プロセスを簡略化し、スムーズなデプロイと使用を確保しています。 115 | 116 | SwiftSoraはシンプルなテキストプロンプトを使用して簡単にビデオ作成を実現し、プロフェッショナルや愛好者がビデオ制作において多機能な人工知能ツールとなっています。 117 | 118 | ### Soraについて [#]{.h-link} 119 | 120 | 2024年2月16日、Open AIは新しい生成型人工知能モデル「Sora」を発表しました。テキストプロンプトを通じて、Soraは直接60秒のビデオを出力し、細部にわたる背景、複雑な多角度のカメラ、感情豊かな複数のキャラクターを含んでいます。 121 | これは、テキストや画像に続き、OpenAIがその先進的なAI技術をビデオ領域に拡張したことを意味しています。OpenAIはまた、Soraが現実世界を理解し模倣できるモデルの基盤であると述べ、この能力はAGI(汎用人工知能)の実現における重要なマイルストーンであると語っています。 122 | 123 | OpenAIのビデオ生成モデルの登場については、業界内では予想があったものの、「想像以上に速い」と評価する人もいれば、「新しい産業革命が始まるのを本当に見ている」と興奮する人もいます。 124 | 125 | 今日まで、**Soraは公開されていません。** ただし、現在はRed Teamメンバーに対してオープンされており、潜在的な危険やリスクを評価するために使用されています。OpenAI Soraチームはまた、ビジュアルアーティスト、デザイナー、映画製作者へのアクセスを拡大し、このモデルを改善し、クリエイティブプロフェッショナルのニーズに応えるためのフィードバックを収集しています。 OpenAIは早期の研究進捗を共有し、組織外の個人と協力し、公に向けて近日公開予定の人工知能機能に関する洞察を提供しています。 126 | 127 | ### デモ 128 | 129 | オンラインデモはこちら 👉🏻👉🏻 [SwiftSora](https://www.swiftsora.com) 130 | 131 | ### ビデオ生成 132 | 133 | 134 | 135 | 136 | 137 | 138 | ### ウェブサイトのホームページ 139 | 140 | 141 | 142 | ### アプリのホームページ 143 | 144 | 145 | 146 | ### コミュニティの最新情報 147 | 148 | 149 | 150 | ### その他のアプリページ 151 | 152 | 153 | 154 | ## 開発への参加 155 | 156 | - `server/routes/fakeOpenAISoraAPI.post.ts` - これは模擬されたOpenAI Sora APIです。公式のSora APIがアクセス可能になったら、このAPIを無効にしてください。 157 | - `server/routes/v1/[...].ts` - これはOpenAI APIのプロキシです。これにより、APIキーが意図せず露出したり、OpenAIによるリスク管理が行われたりすることを防ぎ、APIキーの安全性を確保します。 158 | 159 | このリポジトリをクローンし、依存関係がインストールされていることを確認してください: 160 | 161 | ```bash 162 | # npm 163 | npm install 164 | 165 | # pnpm 166 | pnpm install 167 | 168 | # yarn 169 | yarn install 170 | 171 | # bun 172 | bun install 173 | ``` 174 | 175 | ### 本番環境 176 | 177 | アプリケーションを本番向けにビルドする: 178 | 179 | ```bash 180 | # npm 181 | npm run build 182 | 183 | # pnpm 184 | pnpm run build 185 | 186 | # yarn 187 | yarn build 188 | 189 | # bun 190 | bun run build 191 | ``` 192 | 193 | 本番環境のコードをローカルでプレビューする: 194 | 195 | ```bash 196 | # npm 197 | npm run preview 198 | 199 | # pnpm 200 | pnpm run preview 201 | 202 | # yarn 203 | yarn preview 204 | 205 | # bun 206 | bun run preview 207 | ``` 208 | 209 | 詳細については、[Nuxt.jsデプロイメントドキュメント](https://nuxt.com/docs/getting-started/deployment)を参照してください。 210 | 211 | ## コーヒーをご馳走になってください 212 | 213 | 作者をサポートしてください 214 | 215 | このプロジェクトが楽しく、本当に役立つと感じた場合は、どうかご協力とスターをお願いします。ありがとうございます! 216 | 217 | もしプロジェクトが楽しく、本当に役立つと感じたなら、ご協力とスターをお願いします。 218 | 219 | ### WeChat 220 | 221 | WeChat 222 | 223 | ### Alipay 224 | 225 | Alipay 226 | 227 | ## スターの履歴チャート 228 | 229 | 230 | [![スターの履歴チャート](https://api.star-history.com/svg?repos=jasonwang178/SwiftSora&type=Date)](https://star-history.com/#jasonwang178/SwiftSora&Date) 231 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftSora - AI Video Generator 2 | 3 |
4 | SwiftSora 5 |
6 | 7 | Try Demo here 👉🏻👉🏻 [SwiftSora](https://www.swiftsora.com) 8 | 9 | SwiftSora is an open-source AI video generator built around the OpenAI Sora model. Developed using full-stack technologies, it integrates Nuxt 3, Vue 3, and Tailwind CSS for both frontend and backend functionalities. Featuring a user-friendly web UI, SwiftSora can be easily deployed on platforms like Vercel and Netlify within minutes. 10 | 11 | [![Website Demo](https://img.shields.io/badge/Website-Demo-8A2BE2)](https://www.swiftsora.com) 12 | 13 | ![Stars](https://img.shields.io/github/stars/jasonwang178/swiftsora) ![Forks](https://img.shields.io/github/forks/jasonwang178/swiftsora) 14 | 15 | [English](https://github.com/jasonwang178/SwiftSora/blob/main/README.md) | [简体中文](https://github.com/jasonwang178/SwiftSora/blob/main/README.zh_CN.md) | [日本語](https://github.com/jasonwang178/SwiftSora/blob/main/README.ja_JP.md) 16 | 17 | ## Product Plan 18 | 19 | - [x] Webui + Server 20 | - [ ] SSO - Google, Github and more - WIP 21 | - [ ] Internationalization - WIP 22 | - [x] English 23 | - [x] 简体中文 24 | - [ ] 繁體中文 25 | - [x] 日本語 26 | - [ ] Español 27 | - [ ] 한국어 28 | - [ ] Pricing & Payments 29 | - [ ] Stripe payments 30 | - Deployment 31 | - [x] Vercel 32 | - [x] Netlify 33 | - [ ] Docker 34 | - Security 35 | - [x] OpenAI API Proxy 36 | - API Connection 37 | - [ ] Integration with OpenAI's Sora API (Awaiting the Launch of OpenAI Sora API) 38 | 39 | 40 | ## Deployment 41 | 42 | > [!NOTE] 43 | > This project is experimental. Although it has undergone optimization, caution is still advised. Use it at your own risk, and be aware of any potential consequences. 44 | 45 | ### Vercel 46 | 47 | The preferred deployment option is Vercel, although you have the flexibility to deploy it on any platform of your choice. 48 | 49 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/jasonwang178/SwiftSora) 50 | 51 | 52 | * Select Nuxt.js as the Framework Preset 53 | * Add the following environment variables: 54 | 55 | ```shell 56 | # Your actual OPENAI_API_KEY 57 | OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxx 58 | 59 | # Specify the Sora model name, check at https://platform.openai.com/docs/api-reference 60 | OPENAI_API_MODEL=sora-1.0 61 | 62 | # Set the actual OpenAI base URL or a proxy OpenAI API base URL 63 | # e.g., https://api.openai.com, https://api.myopenaiproxy.com 64 | OPENAI_API_BASE_URL=http://localhost:3000 65 | 66 | # Use this URL as the production host for the application 67 | # Always utilize this proxy URL for secure access to any OpenAI API 68 | # e.g., https://www.swiftsora.com/ 69 | OPENAI_API_PROXY_URL=http://localhost:3000 70 | ``` 71 | 72 | 73 | vercel deployment guide 74 | 75 | Read the Vercel Nuxt deployment guide 👉🏻👉🏻 [here](https://vercel.com/docs/frameworks/nuxt). 76 | 77 | ### Netlify 78 | 79 | You can also deploy it using Netlify. 80 | 81 | [![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/jasonwang178/SwiftSora) 82 | 83 | Read the Netlify Nuxt deployment guide 👉🏻👉🏻 [here](https://docs.netlify.com/integrations/frameworks/nuxt/). 84 | 85 | ### Other platform 86 | 87 | Ensure installed the node.js v18+. 88 | 89 | Add a `.env` file at the home folder. And set the values as mentiond [here](https://github.com/jasonwang178/SwiftSora?tab=readme-ov-file#vercel). 90 | 91 | * Replace the value of `OPENAI_API_PROXY_URL` with your deployed URL. For instance, if you have deployed the project to , update the `OPENAI_API_PROXY_URL` to . 92 | * Adjust the `OPENAI_API_BASE_URL` to your deployed URL temporarily. Once the OpenAI Sora API becomes available, update it to `https://api.openai.com` or any other OpenAI proxy URL. 93 | 94 | Build the application for production: 95 | 96 | ```bash 97 | # npm 98 | npm run build 99 | 100 | # pnpm 101 | pnpm run build 102 | 103 | # yarn 104 | yarn build 105 | 106 | # bun 107 | bun run build 108 | ``` 109 | 110 | Check out the [Nuxt.js deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. 111 | 112 | ## Introduction 113 | 114 | ### About SwiftSora 115 | 116 | SwiftSora is an open-source full-stack platform, combining Nuxt, Vue 3, and Tailwind CSS for both the front-end and back-end. It features a user-friendly web UI and can be easily installed on platforms like Vercel and Netlify within minutes. 117 | 118 | Empowering users to transform text into videos using OpenAI's Sora model, this platform simplifies the video creation process, ensuring smooth deployment and usage. 119 | 120 | SwiftSora enables effortless video creation by simply inputting text, making it a versatile tool for professionals and enthusiasts alike in video production and AI technology. 121 | 122 | ### About Sora 123 | 124 | On February 16, 2024, OpenAI unveiled its groundbreaking generative artificial intelligence model, "Sora." It is reported that Sora can generate a video lasting up to 60 seconds directly from textual prompts, featuring highly detailed backgrounds, intricate multi-angle shots, and emotionally rich characters. 125 | 126 | This signifies OpenAI's expansion of its advanced AI technology into the realm of videos, following text and images. OpenAI also emphasizes that Sora serves as the foundation for a model capable of understanding and **simulating the real world**, marking a significant milestone towards achieving AGI (Artificial General Intelligence). 127 | 128 | The emergence of OpenAI's video generation model was anticipated within the industry, with some noting that it arrived "faster than imagined." Others expressed excitement, stating that "we are truly witnessing the advent of a new industrial revolution." 129 | 130 | As of today, **Sora has not been publicly released.** However, it is currently accessible to Red Team members for evaluating potential risks and critical areas. The OpenAI Sora team has expanded access to visual artists, designers, and filmmakers to gather feedback for improving the model to meet the needs of creative professionals. OpenAI is sharing early research progress, collaborating with individuals outside the organization, and seeking input to provide insights into upcoming AI features for the public. 131 | 132 | [Read more ->](https://openai.com/sora) 133 | 134 | ### Demos 135 | 136 | Try Demo here 👉🏻👉🏻 [SwiftSora](https://www.swiftsora.com) 137 | 138 | ### Video generation 139 | 140 | https://github.com/jasonwang178/SwiftSora/assets/222802/d9752751-a906-4dcc-80d2-b30dc0ccad99 141 | 142 | https://github.com/jasonwang178/SwiftSora/assets/222802/b4c1f5b1-0348-4946-98cd-87647cf81d93 143 | 144 | ### Landing page 145 | 146 | https://github.com/jasonwang178/SwiftSora/assets/222802/18eb7897-7b46-431a-9487-98b8dfa8b804 147 | 148 | ### Application homepage 149 | 150 | https://github.com/jasonwang178/SwiftSora/assets/222802/f6e670a5-d281-4cf2-a8fa-3f38c17155d3 151 | 152 | ### Community feed 153 | 154 | https://github.com/jasonwang178/SwiftSora/assets/222802/842d4ba0-9442-4be5-a1ff-c1283ec9160a 155 | 156 | ### Other Application pages 157 | 158 | https://github.com/jasonwang178/SwiftSora/assets/222802/e8e1a120-4b42-4457-bd09-368c32cc0e18 159 | 160 | 161 | ## Contribution 162 | 163 | * `server/routes/fakeOpenAISoraAPI.post.ts` - This is a fake OpenAI Sora API. Please deactivate this API when the official Sora API becomes accessible. 164 | * `server/routes/v1/[...].ts` - This is an OpenAI API proxy. This measure aims to prevent the inadvertent exposure or risk control by OpenAI of your API key. 165 | 166 | Clone this repository and make sure to install the dependencies: 167 | 168 | ```bash 169 | # npm 170 | npm install 171 | 172 | # pnpm 173 | pnpm install 174 | 175 | # yarn 176 | yarn install 177 | 178 | # bun 179 | bun install 180 | ``` 181 | 182 | ### Development Server 183 | 184 | Start the development server on `http://localhost:3000`: 185 | 186 | ```bash 187 | # npm 188 | npm run dev 189 | 190 | # pnpm 191 | pnpm run dev 192 | 193 | # yarn 194 | yarn dev 195 | 196 | # bun 197 | bun run dev 198 | ``` 199 | 200 | ### Production 201 | 202 | Build the application for production: 203 | 204 | ```bash 205 | # npm 206 | npm run build 207 | 208 | # pnpm 209 | pnpm run build 210 | 211 | # yarn 212 | yarn build 213 | 214 | # bun 215 | bun run build 216 | ``` 217 | 218 | Locally preview production build: 219 | 220 | ```bash 221 | # npm 222 | npm run preview 223 | 224 | # pnpm 225 | pnpm run preview 226 | 227 | # yarn 228 | yarn preview 229 | 230 | # bun 231 | bun run preview 232 | ``` 233 | 234 | Check out the [Nuxt.js deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. 235 | 236 | ## Buy me a coffee 237 | 238 | Support the author 支持作者 239 | 240 | If you find this project enjoyable and genuinely helpful, kindly consider supporting it with your contributions and stars. Thanks! 241 | 如果你喜欢这个项目,并且它对你确实有帮助,请不要吝啬你的Star. 242 | 243 | ## Star History 244 | 245 | [![Star History Chart](https://api.star-history.com/svg?repos=jasonwang178/SwiftSora&type=Date)](https://star-history.com/#jasonwang178/SwiftSora&Date) 246 | -------------------------------------------------------------------------------- /README.zh_CN.md: -------------------------------------------------------------------------------- 1 | # SwiftSora - AI视频生成器 2 | 3 |
4 | SwiftSora 5 |
6 | 7 | 在线Demo在这里 👉🏻👉🏻 [SwiftSora](https://www.swiftsora.com) 8 | 9 | SwiftSora是围绕OpenAI Sora模型打造的一款开源AI视频生成器,采用了全栈开发技术(结合了Nuxt 3、Vue 3和Tailwind CSS),包含前端和后端程序。它具有用户友好的Web UI,并可以在几分钟内轻松安装在诸如Vercel和Netlify之类的平台上。 10 | 11 | [![网站演示](https://img.shields.io/badge/Website-Demo-8A2BE2)](https://www.swiftsora.com) 12 | 13 | ![Stars](https://img.shields.io/github/stars/jasonwang178/swiftsora) ![Forks](https://img.shields.io/github/forks/jasonwang178/swiftsora) 14 | 15 | [English](https://github.com/jasonwang178/SwiftSora/blob/main/README.md) | [简体中文](https://github.com/jasonwang178/SwiftSora/blob/main/README.zh_CN.md) | [日本語](https://github.com/jasonwang178/SwiftSora/blob/main/README.ja_JP.md) 16 | 17 | ## 产品计划 18 | 19 | - [x] Webui + 服务器 20 | - [ ] SSO - Google、Github等 - 进行中 21 | - [ ] 国际化 - 进行中 22 | - [x] 英语 23 | - [x] 简体中文 24 | - [ ] 繁體中文 25 | - [x] 日本語 26 | - [ ] Español 27 | - [ ] 한국어 28 | - [ ] 定价与支付 29 | - [ ] Stripe支付 30 | - 部署 31 | - [x] Vercel 32 | - [x] Netlify 33 | - [ ] Docker 34 | - 安全性 35 | - [x] OpenAI API代理 36 | - API连接 37 | - [ ] 与OpenAI的Sora API集成(等待OpenAI Sora API发布) 38 | 39 | ## 部署 40 | 41 | > [!注意] 42 | > 这个项目是实验性的。尽管经过了优化,仍建议谨慎使用。请自行承担风险,并注意任何潜在后果。 43 | 44 | ### Vercel 45 | 46 | 首选的部署选项是Vercel,您也可以灵活选择在的任何平台上部署它。 47 | 48 | [![使用Vercel部署](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/jasonwang178/SwiftSora) 49 | 50 | - 选择Nuxt.js作为框架预设 51 | - 添加以下环境变量: 52 | 53 | ```shell 54 | # 您的实际OPENAI_API_KEY 55 | OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxx 56 | 57 | # 指定Sora模型名称,在https://platform.openai.com/docs/api-reference检查 58 | OPENAI_API_MODEL=sora-1.0 59 | 60 | # 设置实际的OpenAI API base URL或OpenAI API代理URL 61 | # 例如,https://api.openai.com,https://api.myopenaiproxy.com 62 | OPENAI_API_BASE_URL=http://localhost:3000 63 | 64 | # 使用你部署该项目时的host或域名地址 65 | # 例如,https://www.swiftsora.com/ 66 | OPENAI_API_PROXY_URL=http://localhost:3000 67 | ``` 68 | 69 | vercel部署指南 70 | 71 | 阅读Vercel Nuxt部署指南 👉🏻👉🏻 [这里](https://vercel.com/docs/frameworks/nuxt). 72 | 73 | ### Netlify 74 | 75 | 你也可以使用Netlify进行部署。 76 | 77 | [![部署到Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/jasonwang178/SwiftSora) 78 | 79 | 80 | 阅读Netlify Nuxt部署指南 👉🏻👉🏻 [这里](https://docs.netlify.com/integrations/frameworks/nuxt/)。 81 | 82 | ### 其他平台 83 | 84 | 确保安装了Node.js v18+。 85 | 86 | 在主文件夹下添加一个`.env`文件。并按照[这里](https://github.com/jasonwang178/SwiftSora?tab=readme-ov-file#vercel)的说明设置值。 87 | 88 | - 用你部署的URL替换`OPENAI_API_PROXY_URL`的值。例如,如果你已经将项目部署到了 ,将`OPENAI_API_PROXY_URL`更新为 。 89 | - 临时调整`OPENAI_API_BASE_URL`为你的部署URL。一旦OpenAI Sora API可用,将其更新为`https://api.openai.com`或任何其他OpenAI代理URL。 90 | 91 | 为生产环境构建应用程序: 92 | 93 | ```bash 94 | # npm 95 | npm run build 96 | 97 | # pnpm 98 | pnpm run build 99 | 100 | # yarn 101 | yarn build 102 | 103 | # bun 104 | bun run build 105 | ``` 106 | 107 | 请查看[Nuxt.js部署文档](https://nuxt.com/docs/getting-started/deployment)以获取更多信息。 108 | 109 | ## 介绍 110 | 111 | ### 关于SwiftSora [#]{.h-link} 112 | 113 | SwiftSora是一个开源的AI视频生成器,采用了全栈开发技术(结合了Nuxt、Vue 3和Tailwind CSS),包含前端和后端程序。它具有用户友好的Web UI,并可以在几分钟内轻松安装在诸如Vercel和Netlify之类的平台上。 114 | 115 | 通过使用OpenAI的Sora模型,使用户能够将文本转换为视频,该平台简化了视频创建过程,确保平稳部署和使用。 116 | 117 | SwiftSora通过简单输入文本提示词轻松实现视频创建,成为专业人士和爱好者在视频制作方面的多功能人工智能工具。 118 | 119 | ### 关于Sora [#]{.h-link} 120 | 121 | 在 2024 年 2 月 16 日,Open AI 宣布推出全新的生成式人工智能模型“Sora”。据了解,通过文本提示词,Sora 可以直接输出长达 60 秒的视频,并且包含高度细致的背景、复杂的多角度镜头,以及富有情感的多个角色。 122 | 这意味着,继文本、图像之后,OpenAI 将其先进的 AI 技术拓展到了视频领域。OpenAI 亦表示,Sora 是能**够理解和模拟现实世界**的模型的基础,这一能力将是实现 AGI(通用人工智能)的重要里程碑。 123 | 124 | 对于 OpenAI 视频生成模型的出现,业内其实早有预期,但仍有人评价称“比想象中来得更快”,亦有人振奋地表示“我们真的看到新工业革命来临”。 125 | 126 | 截至今天,**Sora尚未公开使用。** 但目前已经对Red Team人员开放,用于评估潜在危害或风险的关键领域。OpenAI Sora团队还扩大了对视觉艺术家、设计师和电影制片人的访问,以收集有关改进该模型以满足创意专业人士需求的反馈。OpenAI正在分享早期研究进展,与组织外的个人合作并征集反馈,向公众提供有关即将推出的人工智能功能的见解。 127 | 128 | ### 演示 129 | 130 | 在线Demo在这里 👉🏻👉🏻 [SwiftSora](https://www.swiftsora.com) 131 | 132 | ### 视频生成 133 | 134 | 135 | 136 | 137 | 138 | 139 | ### 网站首页 140 | 141 | https://github.com/jasonwang178/SwiftSora/assets/222802/18eb7897-7b46-431a-9487-98b8dfa8b804 142 | 143 | ### 应用首页 144 | 145 | https://github.com/jasonwang178/SwiftSora/assets/222802/f6e670a5-d281-4cf2-a8fa-3f38c17155d3 146 | 147 | ### 社区动态 148 | 149 | https://github.com/jasonwang178/SwiftSora/assets/222802/842d4ba0-9442-4be5-a1ff-c1283ec9160a 150 | 151 | ### 其他应用页面 152 | 153 | https://github.com/jasonwang178/SwiftSora/assets/222802/e8e1a120-4b42-4457-bd09-368c32cc0e18 154 | 155 | 156 | ## 参与开发 157 | 158 | - `server/routes/fakeOpenAISoraAPI.post.ts` - 这是一个模拟的 OpenAI Sora API。请在官方 Sora API 可访问时停用此 API。 159 | - `server/routes/v1/[...].ts` - 这是一个 OpenAI API 代理。此举旨在防止API 密钥的意外暴露或由 OpenAI 风控,确保您的 API 密钥安全。 160 | 161 | 克隆这个仓库,并确保安装了依赖项: 162 | 163 | ```bash 164 | # npm 165 | npm install 166 | 167 | # pnpm 168 | pnpm install 169 | 170 | # yarn 171 | yarn install 172 | 173 | # bun 174 | bun install 175 | ``` 176 | 177 | ### 生产环境 178 | 179 | Build the application for production: 180 | 181 | ```bash 182 | # npm 183 | npm run build 184 | 185 | # pnpm 186 | pnpm run build 187 | 188 | # yarn 189 | yarn build 190 | 191 | # bun 192 | bun run build 193 | ``` 194 | 195 | 本地预览生产环境代码: 196 | 197 | ```bash 198 | # npm 199 | npm run preview 200 | 201 | # pnpm 202 | pnpm run preview 203 | 204 | # yarn 205 | yarn preview 206 | 207 | # bun 208 | bun run preview 209 | ``` 210 | 211 | 查看[Nuxt.js部署文档](https://nuxt.com/docs/getting-started/deployment)获取更多信息。 212 | 213 | ## 请我喝杯咖啡 214 | 215 | Support the author 支持作者 216 | 217 | If you find this project enjoyable and genuinely helpful, kindly consider supporting it with your contributions and stars. Thanks! 218 | 如果你喜欢这个项目,并且它对你确实有帮助,请不要吝啬你的打赏和Star. 219 | 220 | 221 | ### 微信 222 | 223 | 微信 224 | 225 | ### 支付宝 226 | 227 | 支付宝 228 | 229 | ## Star历史图表 230 | 231 | [![Star历史图表](https://api.star-history.com/svg?repos=jasonwang178/SwiftSora&type=Date)](https://star-history.com/#jasonwang178/SwiftSora&Date) 232 | -------------------------------------------------------------------------------- /app.config.ts: -------------------------------------------------------------------------------- 1 | export const aspect_ratios = ['1:1', '16:9', '9:16'] 2 | export const video_styles = { 3 | none: 'None', 4 | _3d_model: '3D Model', 5 | analog_film: 'Analog Film', 6 | anime: 'Anime', 7 | cinematic: 'Cinematic', 8 | comic_book: 'Comic Book', 9 | digital_art: 'Digital Art', 10 | enhance: 'Enhance', 11 | fantasy_art: 'Fantasy Art', 12 | isometric: 'Isometric', 13 | line_art: 'Line Art', 14 | low_poly: 'Low Poly', 15 | modeling_compound: 'Modeling Compound', 16 | neon_punk: 'Neon Punk', 17 | origami: 'Origami', 18 | photographic: 'Photographic', 19 | pixel_art: 'Pixel Art', 20 | tile_texture: 'Tile Texture', 21 | } 22 | 23 | export default defineAppConfig({ 24 | darkModeKey: 'darkMode', 25 | styleKey: 'style', 26 | aspect_ratios, 27 | video_styles, 28 | }) 29 | -------------------------------------------------------------------------------- /app.vue: -------------------------------------------------------------------------------- 1 | 19 | 42 | -------------------------------------------------------------------------------- /assets/css/main.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @font-face { 6 | font-family: 'Plus Jakarta Sans'; 7 | font-weight: 300; 8 | font-display: swap; 9 | src: url(/fonts/PlusJakartaSans-Light.woff2) format('woff2'); 10 | } 11 | @font-face { 12 | font-family: 'Plus Jakarta Sans'; 13 | font-weight: 400; 14 | font-display: swap; 15 | src: url(/fonts/PlusJakartaSans-Regular.woff2) format('woff2'); 16 | } 17 | @font-face { 18 | font-family: 'Plus Jakarta Sans'; 19 | font-weight: 500; 20 | font-display: swap; 21 | src: url(/fonts/PlusJakartaSans-Medium.woff2) format('woff2'); 22 | } 23 | @font-face { 24 | font-family: 'Plus Jakarta Sans'; 25 | font-weight: 600; 26 | font-display: swap; 27 | src: url(/fonts/PlusJakartaSans-SemiBold.woff2) format('woff2'); 28 | } 29 | @font-face { 30 | font-family: 'Plus Jakarta Sans'; 31 | font-weight: 700; 32 | font-display: swap; 33 | src: url(/fonts/PlusJakartaSans-Bold.woff2) format('woff2'); 34 | } 35 | @font-face { 36 | font-family: 'Plus Jakarta Sans'; 37 | font-weight: 800; 38 | font-display: swap; 39 | src: url(/fonts/PlusJakartaSans-ExtraBold.woff2) format('woff2'); 40 | } 41 | @font-face { 42 | font-family: 'Plus Jakarta Sans'; 43 | font-weight: 300; 44 | font-style: italic; 45 | font-display: swap; 46 | src: url(/fonts/PlusJakartaSans-LightItalic.woff2) format('woff2'); 47 | } 48 | @font-face { 49 | font-family: 'Plus Jakarta Sans'; 50 | font-weight: 400; 51 | font-style: italic; 52 | font-display: swap; 53 | src: url(/fonts/PlusJakartaSans-Italic.woff2) format('woff2'); 54 | } 55 | @font-face { 56 | font-family: 'Plus Jakarta Sans'; 57 | font-weight: 500; 58 | font-style: italic; 59 | font-display: swap; 60 | src: url(/fonts/PlusJakartaSans-MediumItalic.woff2) format('woff2'); 61 | } 62 | @font-face { 63 | font-family: 'Plus Jakarta Sans'; 64 | font-weight: 600; 65 | font-style: italic; 66 | font-display: swap; 67 | src: url(/fonts/PlusJakartaSans-SemiBoldItalic.woff2) format('woff2'); 68 | } 69 | @font-face { 70 | font-family: 'Plus Jakarta Sans'; 71 | font-weight: 700; 72 | font-style: italic; 73 | font-display: swap; 74 | src: url(/fonts/PlusJakartaSans-BoldItalic.woff2) format('woff2'); 75 | } 76 | @font-face { 77 | font-family: 'Plus Jakarta Sans'; 78 | font-weight: 800; 79 | font-style: italic; 80 | font-display: swap; 81 | src: url(/fonts/PlusJakartaSans-ExtraBoldItalic.woff2) format('woff2'); 82 | } 83 | 84 | .rad-color-1 { 85 | /* Fallback color */ 86 | background-color: #7857ff; 87 | 88 | background-image: linear-gradient(81.02deg, #fa5560 -23.47%, #b14bf4 45.52%); 89 | 90 | background-size: 100%; 91 | background-repeat: repeat; 92 | -webkit-background-clip: text; 93 | -webkit-text-fill-color: transparent; 94 | -moz-background-clip: text; 95 | -moz-text-fill-color: transparent; 96 | } 97 | .rad-color-2 { 98 | /* Fallback color */ 99 | background-color: #7857ff; 100 | 101 | background: linear-gradient(81.02deg, #b14bf4 -39.48%, #4d91ff 130.8%); 102 | -webkit-background-clip: text; 103 | -webkit-text-fill-color: transparent; 104 | background-clip: text; 105 | -moz-background-clip: text; 106 | text-fill-color: transparent; 107 | } 108 | 109 | .rad-color-full { 110 | /* Fallback color */ 111 | background-color: #7857ff; 112 | 113 | background-image: linear-gradient(81.02deg, #fa5560 -23.47%, #b14bf4 45.52%, #4d91ff 114.8%); 114 | background-size: 100%; 115 | background-repeat: repeat; 116 | -webkit-background-clip: text; 117 | -webkit-text-fill-color: transparent; 118 | -moz-background-clip: text; 119 | -moz-text-fill-color: transparent; 120 | } 121 | 122 | .h1-home { 123 | font-weight: 600; 124 | font-size: clamp(1.5625rem, 0.2717rem + 5.163vw, 2.75rem); 125 | } 126 | 127 | .tab_bg { 128 | background: radial-gradient(80.23% 80.23% at 50% 88.37%, rgba(255, 255, 255, 0.82) 0%, rgba(255, 255, 255, 0.22) 0.01%, rgba(255, 255, 255, 0) 100%); 129 | } 130 | 131 | .home-guide { 132 | @apply z-10 md:bg-gradient-to-b from-transparent text-gray-600 dark:text-white to-black/50 dark:to-white/90 md:text-white md:to-black/50 md:dark:to-black/50 hover:shadow-neutral-300 dark:hover:shadow-neutral-500 shadow md:hover:shadow-neutral-500 hover:shadow-2xl hover:cursor-pointer rounded-md p-4 lg:h-[210px] xl:h-[180px]; 133 | } 134 | .home-guide > a > p { 135 | @apply md:h-14 lg:h-24 xl:h-14; 136 | } 137 | 138 | .home-meta { 139 | @apply h-full sm:h-[294px] md:h-[292px] lg:h-[292px] xl:h-[198px]; 140 | } 141 | .bg { 142 | @apply h-[390px] sm:h-[320px] md:h-[830px] lg:h-[620px] xl:h-[500px]; 143 | } 144 | 145 | /* Styles for screens from 360px to less than 400px */ 146 | @media (min-width: 562px) and (max-width: 639px) { 147 | .bg { 148 | @apply h-[300px]; 149 | } 150 | .home-meta { 151 | @apply h-[240px]; 152 | } 153 | } 154 | 155 | /* Styles for screens from 320px to less than 360px */ 156 | @media (min-width: 515px) and (max-width: 561px) { 157 | .bg { 158 | @apply h-[350px]; 159 | } 160 | .home-meta { 161 | @apply h-[290px]; 162 | } 163 | } 164 | 165 | @media (min-width: 391px) and (max-width: 514px) { 166 | .bg { 167 | @apply h-[350px]; 168 | } 169 | .home-meta { 170 | @apply h-[300px]; 171 | } 172 | } 173 | 174 | @media (max-width: 390px) { 175 | .bg { 176 | @apply h-[390px]; 177 | } 178 | .home-meta { 179 | @apply h-[320px]; 180 | } 181 | } 182 | 183 | #mainContent > h1 { 184 | @apply inline-block mb-2 text-3xl font-extrabold tracking-tight text-gray-900 dark:text-white; 185 | } 186 | #mainContent .h-link { 187 | @apply mb-0.5 ml-2 text-primary-700 opacity-0 transition-opacity dark:text-primary-500 hover:opacity-100; 188 | } 189 | /* #mainContent .h3-link { 190 | @apply ml-2 text-primary-700 opacity-100 transition-opacity dark:text-primary-500 hover:opacity-100; 191 | } */ 192 | #mainContent > h2 { 193 | @apply relative mt-8 mb-4 text-2xl font-semibold dark:text-white; 194 | } 195 | #mainContent > h2:hover, 196 | #mainContent > h3:hover { 197 | .h-link { 198 | @apply opacity-100; 199 | } 200 | } 201 | 202 | #mainContent > h3, 203 | #mainContent > h4 { 204 | @apply mt-8 mb-4 text-xl font-semibold dark:text-white; 205 | } 206 | 207 | #mainContent > p { 208 | @apply mb-4 text-base font-normal text-gray-600 dark:text-gray-400; 209 | } 210 | 211 | #mainContent > p > a, 212 | #mainContent > ul > li > a, 213 | #mainContent > ol > li > a, 214 | #mainContent > ul > li > p > a, 215 | #mainContent > ol > li > p > a { 216 | @apply font-medium text-gray-700 underline dark:text-gray-300 decoration-1 underline-offset-2 decoration-primary-600 dark:decoration-primary-500; 217 | } 218 | 219 | #mainContent > p > a:hover, 220 | #mainContent > ul > li > a:hover, 221 | #mainContent > ol > li > a:hover, 222 | #mainContent > ul > li > p > a:hover, 223 | #mainContent > ol > li > p > a:hover { 224 | @apply text-gray-900 decoration-2 dark:text-white; 225 | } 226 | 227 | #mainContent > p > code, 228 | #mainContent > ul > li > code, 229 | #mainContent > ol > li > code { 230 | @apply px-1 font-mono text-sm text-primary-600 break-all dark:text-primary-400; 231 | } 232 | 233 | #mainContent > ul { 234 | list-style: disc; 235 | } 236 | 237 | #mainContent > ol { 238 | list-style: decimal; 239 | } 240 | 241 | #mainContent p > strong { 242 | @apply text-gray-900 dark:text-white; 243 | } 244 | 245 | #mainContent > ul, 246 | #mainContent > ol { 247 | padding-left: 1rem; 248 | } 249 | 250 | #mainContent > ul > li, 251 | #mainContent > ol > li { 252 | @apply mb-4 text-base font-normal text-gray-600 dark:text-gray-400; 253 | } 254 | 255 | .highlight { 256 | @apply overflow-hidden; 257 | } 258 | 259 | /* without preview */ 260 | .highlight pre[class*='language-'] { 261 | overflow: auto; 262 | @apply p-6 pt-6 m-0 mt-4 mb-8 text-sm bg-gray-50 rounded-xl dark:bg-gray-800; 263 | } 264 | 265 | [data-code-wrapper] .highlight pre[class*='language-'] { 266 | @apply my-0; 267 | } 268 | 269 | /* when after preview */ 270 | .code-preview-wrapper + .code-syntax-wrapper > .code-syntax > .relative > [data-code-wrapper] > .highlight pre[class*='language-'], 271 | .code-preview-wrapper + .code-syntax-wrapper > .code-syntax { 272 | overflow-y: hidden; 273 | overflow-x: scroll; 274 | @apply mt-0 rounded-none; 275 | } 276 | 277 | .code-preview-wrapper + .code-syntax-wrapper { 278 | @apply mb-4; 279 | } 280 | 281 | .code-preview-wrapper + .code-syntax-wrapper > .code-syntax > .relative > [data-code-wrapper] > .highlight > pre[class*='language-'] { 282 | @apply p-4 m-0 bg-gray-50 dark:bg-gray-800; 283 | } 284 | 285 | :not(pre) > code[class*='language-'], 286 | pre[class*='language-'] { 287 | @apply bg-gray-50 dark:bg-gray-800; 288 | } 289 | 290 | /* Inline code */ 291 | :not(pre) > code[class*='language-'] { 292 | padding: 0.1em; 293 | border-radius: 0.3em; 294 | } 295 | 296 | .token.comment, 297 | .token.prolog, 298 | .token.doctype, 299 | .token.cdata { 300 | @apply text-gray-800 dark:text-gray-400; 301 | } 302 | 303 | .token.punctuation { 304 | @apply text-gray-800 dark:text-gray-400; 305 | } 306 | 307 | .namespace { 308 | opacity: 0.7; 309 | } 310 | 311 | .token.property, 312 | .token.keyword, 313 | .token.tag { 314 | @apply text-pink-700 dark:text-pink-400; 315 | } 316 | 317 | .token.class-name { 318 | @apply text-violet-700 dark:text-violet-400; 319 | text-decoration: underline; 320 | } 321 | 322 | .token.boolean, 323 | .token.constant { 324 | @apply text-green-600 dark:text-green-400; 325 | } 326 | 327 | .token.symbol, 328 | .token.deleted { 329 | @apply text-red-500 dark:text-red-400; 330 | } 331 | 332 | .token.number { 333 | @apply text-violet-700 dark:text-violet-400; 334 | } 335 | 336 | .token.selector, 337 | .token.attr-name, 338 | .token.string, 339 | .token.char, 340 | .token.builtin, 341 | .token.inserted { 342 | @apply text-sky-600 dark:text-sky-500; 343 | } 344 | 345 | .token.variable { 346 | @apply text-purple-500 dark:text-purple-400; 347 | } 348 | 349 | .token.operator { 350 | @apply text-gray-500 dark:text-gray-400 dark:bg-gray-800; 351 | } 352 | 353 | .token.entity { 354 | @apply text-yellow-400 dark:text-yellow-300; 355 | cursor: help; 356 | } 357 | 358 | .token.url { 359 | @apply text-primary-600 dark:text-primary-500; 360 | } 361 | 362 | .language-css .token.string, 363 | .style .token.string { 364 | @apply text-red-500 dark:text-red-400; 365 | } 366 | 367 | .token.atrule, 368 | .token.attr-value { 369 | @apply text-primary-600 dark:text-primary-500; 370 | } 371 | 372 | .token.function { 373 | @apply text-cyan-700 dark:text-cyan-500; 374 | } 375 | 376 | .token.regex { 377 | color: #e9c062; 378 | } 379 | 380 | .token.important { 381 | color: #fd971f; 382 | } 383 | 384 | .token.important, 385 | .token.bold { 386 | font-weight: bold; 387 | } 388 | 389 | .token.italic { 390 | font-style: italic; 391 | } 392 | 393 | code.language-bash, 394 | pre.language-bash { 395 | @apply text-primary-600 dark:text-primary-400; 396 | } 397 | 398 | code.language-javascript { 399 | @apply text-primary-600 dark:text-primary-400; 400 | } 401 | 402 | code.language-javascript .token.function { 403 | @apply text-green-500 dark:text-green-300; 404 | } 405 | 406 | code.language-javascript .token.punctuation { 407 | @apply text-gray-500 dark:text-gray-400; 408 | } 409 | 410 | code.language-javascript .token.keyword { 411 | @apply text-pink-500 dark:text-pink-400; 412 | } 413 | 414 | code.language-javascript .token.comment { 415 | @apply text-gray-500 dark:text-gray-500; 416 | } 417 | 418 | code.language-javascript .token.string { 419 | @apply text-purple-600 dark:text-purple-400; 420 | } 421 | 422 | code.language-javascript .token.class-name { 423 | @apply text-orange-400 dark:text-orange-300; 424 | } 425 | 426 | code.language-javascript .token { 427 | /* @apply text-primary-900 dark:text-primary-500; */ 428 | background: transparent; 429 | } 430 | 431 | /* language html */ 432 | code.language-html .token.tag { 433 | @apply text-fuchsia-700 dark:text-fuchsia-400; 434 | } 435 | code.language-html .token.attr-value { 436 | @apply text-primary-600 dark:text-primary-400; 437 | } 438 | code.language-html .token.punctuation { 439 | @apply text-gray-400 dark:text-gray-500; 440 | } 441 | code.language-html .token.attr-name { 442 | @apply text-green-600 dark:text-green-400; 443 | } 444 | code.language-html .token.comment { 445 | @apply text-gray-400 dark:text-gray-500; 446 | } 447 | 448 | .code-responsive-wrapper { 449 | background-color: #ffffff; 450 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23d1d5db' fill-opacity='0.4'%3E%3Cpath opacity='.5' d='M96 95h4v1h-4v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9zm-1 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9z'/%3E%3Cpath d='M6 5V0H5v5H0v1h5v94h1V6h94V5H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); 451 | } 452 | .dark .code-responsive-wrapper { 453 | background-color: #111827; 454 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%236b7280' fill-opacity='0.4'%3E%3Cpath opacity='.5' d='M96 95h4v1h-4v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9zm-1 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9z'/%3E%3Cpath d='M6 5V0H5v5H0v1h5v94h1V6h94V5H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); 455 | } 456 | -------------------------------------------------------------------------------- /components/AppNav.vue: -------------------------------------------------------------------------------- 1 | 79 | -------------------------------------------------------------------------------- /components/AppSidebar.vue: -------------------------------------------------------------------------------- 1 | 102 | 103 | 106 | -------------------------------------------------------------------------------- /components/AppVideoFeed.vue: -------------------------------------------------------------------------------- 1 | 106 | 107 | 180 | -------------------------------------------------------------------------------- /components/LangTheme.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 86 | -------------------------------------------------------------------------------- /components/LocLink.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /components/Logo.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | -------------------------------------------------------------------------------- /components/SiteFooterSection.vue: -------------------------------------------------------------------------------- 1 | 83 | 86 | -------------------------------------------------------------------------------- /components/SiteNav.vue: -------------------------------------------------------------------------------- 1 | 44 | -------------------------------------------------------------------------------- /components/Social.vue: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /components/content/Resources.vue: -------------------------------------------------------------------------------- 1 | 37 | -------------------------------------------------------------------------------- /composables/states.ts: -------------------------------------------------------------------------------- 1 | import { type Video } from '~/server/models/Video' 2 | export const useCommunityVideos = () => useState('communityVideos', () => []) 3 | export const useCommunityVideosPending= () => useState('communityVideosPending', () => []) 4 | export const useDarkMode = () => useState('darkMode', () => '1') 5 | -------------------------------------------------------------------------------- /content/en-US/app/docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Documentation - App | SwiftSora - AI Video Generator - Create Video, Images & More | SwiftSora 3 | short: 4 | tags: 5 | --- 6 | # SwiftSora - AI Video Generator 7 | 8 | [Get started with the leading open-source video generator, which is built with the full-stack combination of Nuxt, Vue 3, and Tailwind CSS, centered around OpenAI Sora API.]{.text-lg .text-gray-600 .dark:text-gray-400} 9 | 10 |
11 | 12 | --- 13 | 14 | ## Introduction [#]{.h-link} 15 | 16 | 17 | 18 | ### About SwiftSora [#]{.h-link} 19 | 20 | SwiftSora is an open-source full-stack platform, combining Nuxt, Vue 3, and Tailwind CSS for both the front-end and back-end. It features a user-friendly web UI and can be easily installed on platforms like Vercel and Netlify within minutes. 21 | 22 | Empowering users to transform text into videos using OpenAI's Sora model, this platform simplifies the video creation process, ensuring smooth deployment and usage. 23 | 24 | SwiftSora enables effortless video creation by simply inputting text, making it a versatile tool for professionals and enthusiasts alike in video production and AI technology. 25 | 26 | ### About Sora [#]{.h-link} 27 | 28 | On February 16, 2024, OpenAI unveiled its groundbreaking generative artificial intelligence model, "Sora." It is reported that Sora can generate a video lasting up to 60 seconds directly from textual prompts, featuring highly detailed backgrounds, intricate multi-angle shots, and emotionally rich characters. 29 | 30 | This signifies OpenAI's expansion of its advanced AI technology into the realm of videos, following text and images. OpenAI also emphasizes that Sora serves as the foundation for a model capable of understanding and **simulating the real world**, marking a significant milestone towards achieving AGI (Artificial General Intelligence). 31 | 32 | The emergence of OpenAI's video generation model was anticipated within the industry, with some noting that it arrived "faster than imagined." Others expressed excitement, stating that "we are truly witnessing the advent of a new industrial revolution." 33 | 34 | As of today, **Sora has not been publicly released.** However, it is currently accessible to Red Team members for evaluating potential risks and critical areas. The OpenAI Sora team has expanded access to visual artists, designers, and filmmakers to gather feedback for improving the model to meet the needs of creative professionals. OpenAI is sharing early research progress, collaborating with individuals outside the organization, and seeking input to provide insights into upcoming AI features for the public. 35 | 36 | 37 | [Read more :icon{name="material-symbols:arrow-right-alt" class="w-5 h-5"}](https://openai.com/sora) 38 | 39 | ### Rapid Deployment [#]{.h-link} 40 | 41 | Effortlessly deploy with a single click to Vercel, Netlify and other platforms. 42 | 43 | [Get started now](https://github.com/jasonwang178/SwiftSora) 44 | 45 | SwiftSora enables effortless video creation by simply inputting text, making it a versatile tool for professionals and enthusiasts alike in video production and AI technology. 46 | 47 | ### Secure your API key [#]{.h-link} 48 | 49 | SwiftSora now includes a straightforward server backend. To ensure the safety of OpenAI usage in certain regions, SwiftSora has introduced an additional layer of API proxy. This measure aims to prevent the inadvertent exposure or risk control by OpenAI of your API key. During deployment, you only need to set your SwiftSora domain as `OPENAI_API_PROXY_URL` in the `.env` file. 50 | 51 | Additionally, besides the official OpenAI AI, we support any API service that aligns with OpenAI API standards. Simply set `OPENAI_API_BASE_URL` to your API service provider's base URL during deployment 52 | 53 | ## Resources [#]{.h-link} 54 | 55 | :resources 56 | 57 | ### Encountered any bugs? 58 | 59 | Kindly report them by [creating an issue](https://github.com/jasonwang178/SwiftSora/issues). 60 | -------------------------------------------------------------------------------- /content/ja-JP/app/docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ドキュメント - アプリ | SwiftSora - AIビデオジェネレーター - テキストからビデオと画像を生成する | SwiftSora 3 | short: 4 | tags: 5 | --- 6 | 7 | # SwiftSora - AIビデオジェネレーター 8 | 9 | [最新のオープンソースビデオジェネレーターを利用して、Nuxt、Vue 3、およびTailwind CSSのフルスタックコンボを使用し、OpenAI Sora APIを中心に構築されたものをお試しください。]{.text-lg .text-gray-600 .dark:text-gray-400} 10 | 11 | --- 12 | 13 | ## はじめに [#]{.h-link} 14 | 15 | ### SwiftSoraについて [#]{.h-link} 16 | 17 | SwiftSoraは、オープンソースのAIビデオジェネレーターで、Nuxt、Vue 3、およびTailwind CSSを組み合わせたフルスタック開発技術を採用しています。フレンドリーなWeb UIを備えており、VercelやNetlifyなどのプラットフォームに簡単にインストールできます。 18 | 19 | OpenAIのSoraモデルを使用することで、テキストをビデオに変換でき、ビデオ作成プロセスを簡略化し、スムーズなデプロイと使用を保証します。 20 | 21 | SwiftSoraは、テキストプロンプトを入力するだけでビデオ作成を容易にし、プロフェッショナルやアマチュアのビデオ制作者にとって多機能なAIツールとなっています。 22 | 23 | ### Soraについて [#]{.h-link} 24 | 25 | 2024年2月16日、OpenAIは新しい生成型人工知能モデル「Sora」を発表しました。テキストプロンプトを使用することで、Soraは最大60秒のビデオを直接出力し、細かい背景、複雑な多角度のショット、感情豊かな複数のキャラクターを含みます。 26 | これは、テキストや画像に続き、OpenAIが先進のAI技術をビデオ領域に拡張したものです。OpenAIはまた、Soraが**現実世界を理解し模倣する**能力を持つモデルであることを強調し、この能力はAGI(汎用人工知能)の達成に向けた重要なマイルストーンであると述べています。 27 | 28 | OpenAIビデオ生成モデルの登場は、業界内で予想されていたものですが、「予想以上に速い」と評価する人もいますし、「新たな産業革命がやってきた」と振り返る人もいます。 29 | 30 | 現時点では、**Soraはまだ一般に利用されていません。** ただし、Red Teamメンバーには利用が開放されており、潜在的なリスクや危険性を評価するための重要な領域に利用されています。OpenAI Soraチームは、ビジュアルアーティスト、デザイナー、映画製作者へのアクセスを拡大し、このモデルを向上させ、クリエイティブプロフェッショナルのニーズに応えるためのフィードバックを収集しています。OpenAIは、早期の研究進捗を共有し、組織外の個人と協力し、公開されるAI機能に関する洞察を提供しています。 31 | 32 | [詳細はこちら :icon{name="material-symbols:arrow-right-alt" class="w-5 h-5"}](https://openai.com/sora) 33 | 34 | ### クイックデプロイ [#]{.h-link} 35 | 36 | Vercel、Netlifyなどへのワンクリックデプロイが簡単に行えます。 37 | 38 | [今すぐ始める](https://github.com/jasonwang178/SwiftSora) 39 | 40 | SwiftSoraはシンプルなテキスト入力で簡単にビデオ作成ができ、プロフェッショナルや愛好者のための多機能なツールとなっています。 41 | 42 | ### APIキーの保護 [#]{.h-link} 43 | 44 | SwiftSoraにはシンプルなサーバーバックエンドが含まれています。特定の地域でOpenAIを安全に使用するために、SwiftSoraはAPIプロキシの追加レイヤーを導入しています。これにより、APIキーの意図しない露出やOpenAIによるリスクをコントロールすることができます。デプロイの際には、`.env`ファイルでSwiftSoraドメインを`OPENAI_API_PROXY_URL`に設定するだけです。 45 | 46 | さらに、公式のOpenAI AIだけでなく、OpenAI API標準に従った任意のAPIサービスもサポートしています。デプロイの際には、`OPENAI_API_BASE_URL`をAPIサービスプロバイダーの基本URLに設定するだけです。 47 | 48 | ## リソース [#]{.h-link} 49 | 50 | :resources 51 | 52 | ### バグを見つけましたか? 53 | 54 | 報告はGitHubの[Issueを作成](https://github.com/jasonwang178/SwiftSora/issues)してください。 55 | -------------------------------------------------------------------------------- /content/zh-CN/app/docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 文档 - 应用 | SwiftSora - AI视频生成器 - 通过文字生成视频和图片 | SwiftSora 3 | short: 4 | tags: 5 | --- 6 | 7 | # SwiftSora - AI视频生成器 8 | 9 | [开始使用先进的开源视频生成器,采用Nuxt、Vue 3和Tailwind CSS的全栈组合,围绕OpenAI Sora API而打造。]{.text-lg .text-gray-600 .dark:text-gray-400} 10 | 11 |
12 | 13 | --- 14 | 15 | ## 介绍 [#]{.h-link} 16 | 17 | 18 | 19 | ### 关于SwiftSora [#]{.h-link} 20 | 21 | SwiftSora是一个开源的AI视频生成器,采用了全栈开发技术(结合了Nuxt、Vue 3和Tailwind CSS),包含前端和后端程序。它具有用户友好的Web UI,并可以在几分钟内轻松安装在诸如Vercel和Netlify之类的平台上。 22 | 23 | 通过使用OpenAI的Sora模型,使用户能够将文本转换为视频,该平台简化了视频创建过程,确保平稳部署和使用。 24 | 25 | SwiftSora通过简单输入文本提示词轻松实现视频创建,成为专业人士和爱好者在视频制作方面的多功能人工智能工具。 26 | 27 | ### 关于Sora [#]{.h-link} 28 | 29 | 在 2024 年 2 月 16 日,Open AI 宣布推出全新的生成式人工智能模型“Sora”。据了解,通过文本提示词,Sora 可以直接输出长达 60 秒的视频,并且包含高度细致的背景、复杂的多角度镜头,以及富有情感的多个角色。 30 | 这意味着,继文本、图像之后,OpenAI 将其先进的 AI 技术拓展到了视频领域。OpenAI 亦表示,Sora 是能**够理解和模拟现实世界**的模型的基础,这一能力将是实现 AGI(通用人工智能)的重要里程碑。 31 | 32 | 对于 OpenAI 视频生成模型的出现,业内其实早有预期,但仍有人评价称“比想象中来得更快”,亦有人振奋地表示“我们真的看到新工业革命来临”。 33 | 34 | 截至今天,**Sora尚未公开使用。** 但目前已经对Red Team人员开放,用于评估潜在危害或风险的关键领域。OpenAI Sora团队还扩大了对视觉艺术家、设计师和电影制片人的访问,以收集有关改进该模型以满足创意专业人士需求的反馈。OpenAI正在分享早期研究进展,与组织外的个人合作并征集反馈,向公众提供有关即将推出的人工智能功能的见解。 35 | 36 | [了解更多 :icon{name="material-symbols:arrow-right-alt" class="w-5 h-5"}](https://openai.com/sora) 37 | 38 | ### 快速部署 [#]{.h-link} 39 | 40 | 轻松一键部署到Vercel、Netlify和其他平台。 41 | 42 | [立即开始](https://github.com/jasonwang178/SwiftSora) 43 | 44 | SwiftSora通过简单输入文本实现轻松视频创建,成为专业人士和爱好者在视频制作和人工智能技术方面的多功能工具。 45 | 46 | ### 保护您的API密钥 [#]{.h-link} 47 | 48 | SwiftSora现在包括一个简单的服务器后端。为了确保在某些地区安全使用OpenAI,SwiftSora引入了API代理的附加层。此举旨在防止意外曝露或OpenAI对您的API密钥的风险控制。在部署过程中,您只需要在`.env`文件中将您的SwiftSora域设置为`OPENAI_API_PROXY_URL`。 49 | 50 | 此外,除了官方的OpenAI AI,我们还支持与OpenAI API标准一致的任何API服务。只需在部署过程中将`OPENAI_API_BASE_URL`设置为您的API服务提供商的基本URL。 51 | 52 | ## 资源 [#]{.h-link} 53 | 54 | :resources 55 | 56 | ### 发现Bug了吗? 57 | 58 | 请到移步Github[创建Issue](https://github.com/jasonwang178/SwiftSora/issues)进行报告。 59 | -------------------------------------------------------------------------------- /error.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 88 | -------------------------------------------------------------------------------- /i18n.config.ts: -------------------------------------------------------------------------------- 1 | export default defineI18nConfig(() => ({ 2 | legacy: false, 3 | fallbackLocale: { 4 | en: ['en-US'], 5 | }, 6 | })) 7 | -------------------------------------------------------------------------------- /lang/en-US.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | app_title: 'SwiftSora - AI Video Generator - Create Video, Images & More | SwiftSora', 3 | seo: { 4 | ogTitle: 'SwiftSora - AI Video Generator - Create Video, Images & More | SwiftSora', 5 | description: 6 | "Generate videos and images effortlessly with SwiftSora, an open-source project using OpenAI's powerful Sora model. One-click deployment to Vercel and more. Developed with Nuxt.js, Vue 3 and Tailwind CSS in a full-stack configuration. Secure your API key with the built-in OpenAI proxy.", 7 | ogDescription: 8 | "Generate videos and images effortlessly with SwiftSora, an open-source project using OpenAI's powerful Sora model. One-click deployment to Vercel and more. Developed with Nuxt.js, Vue 3 and Tailwind CSS in a full-stack configuration. Secure your API key with the built-in OpenAI proxy.", 9 | keywords: 'AI,OpenAI,Sora,Video Generation,SwiftSora', 10 | }, 11 | error: { 12 | e404: { 13 | title: 'Page not found', 14 | desc: 'Oops! Looks like you followed a bad link. If you think this is a problem with us, please tell us.', 15 | link: '', 16 | desc2: '', 17 | }, 18 | e500: { 19 | title: 'Something has gone seriously wrong', 20 | desc: "It's always time for a coffee break. We should be back by the time you finish your coffee.", 21 | link: '', 22 | desc2: '', 23 | }, 24 | e502: { 25 | title: 'Under Maintenance', 26 | desc: 'Sorry for the inconvenience but we’re performing some maintenance at the moment. If you need to you can always ', 27 | link: 'contact us', 28 | desc2: ', otherwise we’ll be back online shortly!.', 29 | }, 30 | video_not_supported: 'Your browser does not support the video tag.', 31 | validation: { 32 | video_gen: { 33 | error1: "You didn't provide a Prompt.", 34 | error2: "You didn't upload an Image.", 35 | }, 36 | }, 37 | }, 38 | common: { 39 | loading: 'Loading...', 40 | read_more: 'Read more', 41 | go_home: 'Go back home', 42 | }, 43 | // components 44 | site_nav: { 45 | tip: 'Open main menu', 46 | video_gallery: 'Video Gallery', 47 | blog: 'Blog', 48 | gen_video: 'Generate a Video', 49 | }, 50 | lang_theme: { 51 | tip: 'Toggle dark mode', 52 | }, 53 | site_footer: { 54 | intro: "SwiftSora is an open-source project that enables users to generate videos from prompt text online. The project utilizes OpenAI's Sora model to streamline video creation and includes a straightforward one-click website deployment feature.", 55 | about: 'About', 56 | blog: 'Blog', 57 | faq: 'FAQ', 58 | docs: 'Docs', 59 | contact: 'Contact us', 60 | stay_tuned: 'Stay tuned!', 61 | discord: 'Discord', 62 | twitter: 'Twitter', 63 | github: 'Github', 64 | youtube: 'YouTube Community', 65 | legal: 'Legal', 66 | license: 'License (Apache 2.0)', 67 | dmca: 'DMCA', 68 | legal_notice: 'Privacy Policy', 69 | terms: 'Terms of Service', 70 | cookie_policy: 'Cookie Policy', 71 | rights: 'All Rights Reserved.', 72 | }, 73 | app_nav: { 74 | tip: 'Open user menu', 75 | settings: 'Settings', 76 | signout: 'Sign out', 77 | }, 78 | app_sidebar: { 79 | home: 'Home', 80 | community_feed: 'Community Feed', 81 | personal_feed: 'Personal Feed', 82 | user_tools1: 'User', 83 | user_tools2: 'Tools', 84 | video_gen: 'Video Generation', 85 | docs: 'Docs', 86 | faq: 'FAQ & Help', 87 | }, 88 | index: { 89 | title: '', 90 | intro1: 'Unleash your ', 91 | intro2: 'creativity', 92 | intro3: 'with the capabilities of ', 93 | sub_intro: 'Produce high-quality video assets for you with unparalleled excellence in terms of quality, speed, and stylistic consistency.', 94 | gen_video: 'Generate a Video', 95 | guide1: { 96 | title: 'What is Sora?', 97 | desc: 'Sora is an AI model that can create realistic and imaginative scenes from text instructions.', 98 | }, 99 | guide2: { 100 | title: 'What is SwiftSora?', 101 | desc: "An open-source project using OpenAI's powerful Sora model. Built with full-stack Nuxt.js, Vue 3 and Tailwind CSS.", 102 | }, 103 | guide3: { 104 | title: 'Rapid Deployment', 105 | desc: 'Effortlessly deploy with a single click to Vercel, Netlify and other platforms.', 106 | }, 107 | guide4: { 108 | title: 'Secure your API key', 109 | desc: 'Secure your API key with the built-in OpenAI proxy.', 110 | }, 111 | toolkit: { 112 | title1: 'SwiftSora’s', 113 | title2: ' Toolkit ', 114 | menu1: { 115 | title: 'Video Generation', 116 | sub_title: 'Prompt/Video/Image to Video', 117 | desc1: 118 | "Elevate your creativity to new heights with our Video & Image Generation tool, unlocking transformative capabilities. It goes beyond merely bringing your ideas to life; it redefines the boundaries of possibility. Whether you're a novice or an expert, we provide a range of intuitive settings that can be customized to meet your specific requirements. Generate videos and images effortlessly using natural language prompts, visual cues, text, speech, images, or video.", 119 | desc2: 'Experience an unparalleled blend of simplicity and power, meticulously crafted to cater to creative minds of every proficiency level.', 120 | }, 121 | menu2: { 122 | title: 'Video Editing', 123 | sub_title: 'Edit your video with prompt text', 124 | desc1: 'Beyond bringing your visions to life, SwiftSora extends its prowess to redefine the art of video manipulation. Seamlessly edit, organize, and modify videos with intuitive controls that empower both novices and seasoned professionals', 125 | desc2: 126 | 'From effortless transmission to streamlined sharing, our platform offers an unparalleled fusion of simplicity and power. Craft compelling narratives with the ability to enhance, trim, and transform your videos. Organize seamlessly, modify with precision, and share your creations effortlessly.', 127 | }, 128 | menu3: { 129 | title: 'Video Recognition', 130 | sub_title: 'Video to Text', 131 | desc1: 132 | "Unleash the revolutionary capabilities of our Video & Image Generation tool – not just limited to creative expression but a powerhouse for recognition, processing, analysis, understanding, and generation. Tailored for both beginners and experts, this tool transcends boundaries with its intuitive settings. Whether it's natural language prompts, visual cues, text, speech, or multimedia, experience the seamless fusion of simplicity and power.", 133 | desc2: "Redefine what's possible as you navigate effortlessly through recognition to generation, making it an essential for every creative mind. Elevate your projects with a tool that adapts to your needs, offering unparalleled versatility and efficiency.", 134 | }, 135 | }, 136 | video_gallery: { 137 | title1: 'Video', 138 | title2: ' Gallery ', 139 | sub_title: 'SwiftSora-generated Videos', 140 | more: 'Explore more videos', 141 | }, 142 | }, 143 | app: { 144 | index: { 145 | title: 'Home - App', 146 | page_title: { 147 | pre: 'Get Started ', 148 | post: 'Here', 149 | }, 150 | get_start: { 151 | menu1: { 152 | title: 'Video Generation', 153 | desc: 'Generate video with prompts, videos, images and more.', 154 | }, 155 | menu2: { 156 | title: 'Video Editing', 157 | desc: 'Edit the video using the provided prompts, videos, images.', 158 | }, 159 | menu3: { 160 | title: 'Video Recognition', 161 | desc: 'Submit your video, and automatically create a clear and engaging video description and prompt.', 162 | }, 163 | }, 164 | page_title2: { 165 | pre: 'Recent ', 166 | post: 'Creations', 167 | }, 168 | }, 169 | community_feed: { 170 | title: 'Community Feed - App', 171 | page_title: { 172 | pre: 'Community ', 173 | post: 'Feed', 174 | sub: 'All videos on this page were generated directly by Sora without modification.', 175 | }, 176 | }, 177 | personal_feed: { 178 | title: 'Personal Feed - App', 179 | page_title: { 180 | pre: 'Personal ', 181 | post: 'Feed', 182 | sub: 'Videos produced by yourself.', 183 | }, 184 | }, 185 | video_gen: { 186 | title: 'Video Generation - App', 187 | load: { 188 | title: 'Video generating...', 189 | desc: 'Your video will be ready in a few minutes', 190 | desc2: { 191 | pre: 'The generated video will be saved to your ', 192 | post: 'Personal Feed', 193 | }, 194 | guide: { 195 | title: 'While you wait...', 196 | desc: 'Take a look at other video creations', 197 | }, 198 | }, 199 | text: { 200 | title: 'Text', 201 | guide: { 202 | title: 'Text Prompt', 203 | desc: 'Use a text prompt to generate images. Next, you will select an image to generate a video.', 204 | btn: 'Try sample prompt', 205 | }, 206 | aspect_ration: { 207 | title: 'Aspect Ratio', 208 | placeholder: 'Describe your image.', 209 | }, 210 | style: { 211 | title: 'Style', 212 | video_styles: { 213 | none: 'None', 214 | _3d_model: '3D Model', 215 | analog_film: 'Analog Film', 216 | anime: 'Anime', 217 | cinematic: 'Cinematic', 218 | comic_book: 'Comic Book', 219 | digital_art: 'Digital Art', 220 | enhance: 'Enhance', 221 | fantasy_art: 'Fantasy Art', 222 | isometric: 'Isometric', 223 | line_art: 'Line Art', 224 | low_poly: 'Low Poly', 225 | modeling_compound: 'Modeling Compound', 226 | neon_punk: 'Neon Punk', 227 | origami: 'Origami', 228 | photographic: 'Photographic', 229 | pixel_art: 'Pixel Art', 230 | tile_texture: 'Tile Texture', 231 | }, 232 | }, 233 | }, 234 | image: { 235 | title: 'Image', 236 | tip: 'For best results, please upload an image with a resolution of 1024 × 576px, 576 x 1024px, or 768 × 768px.', 237 | guide: { 238 | title: 'Image Uplaod', 239 | desc: 'Upload an image to generate a video.', 240 | uploader: { 241 | title: { 242 | pre: 'Click to upload', 243 | post: ' or drag and drop', 244 | }, 245 | supported_file: 'PNG, JPG or GIF', 246 | }, 247 | }, 248 | }, 249 | btn_reset: 'Reset', 250 | btn_gen: 'Generate', 251 | }, 252 | docs: { 253 | title: 'Documentation - App', 254 | resources: { 255 | quickstart: { 256 | title: 'Quickstart', 257 | desc: 'Learn how to get started by configuring and deploying SwiftSora.', 258 | }, 259 | github: { 260 | title: 'Like it? Give it a star!', 261 | desc: 'The source code files are also available to be cloned or downloaded from the official SwiftSora Github repository. Don’t forget to give it a star if you appreciate the project.', 262 | }, 263 | contribution: { 264 | title: 'Contribution', 265 | desc: 'Learn how to get started by contrubuting SwiftSora locally on your machine and start developing.', 266 | }, 267 | license: { 268 | title: 'License', 269 | desc: 'Our open-source initiative encourages innovation, sharing, and community growth. Dive into a world where your creativity knows no bounds.', 270 | }, 271 | blog: { 272 | title: 'Blog', 273 | desc: 'Discover additional SwiftSora resources and more on our Official Blog.', 274 | }, 275 | contact: { 276 | title: 'Contact us', 277 | desc: 'Feel free to join the Discord community and ask us any questions about SwiftSora.', 278 | }, 279 | }, 280 | }, 281 | }, 282 | } 283 | -------------------------------------------------------------------------------- /lang/ja-JP.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | app_title: 'SwiftSora - AIビデオジェネレーター - テキストから動画や画像を生成 | SwiftSora', 3 | seo: { 4 | ogTitle: 'SwiftSora - AIビデオジェネレーター - テキストから動画や画像を生成 | SwiftSora', 5 | description: 6 | 'SwiftSoraを使用して簡単に動画や画像を生成しましょう。これはOpenAIの強力なSoraモデルを使用したオープンソースプロジェクトです。Vercelなどのプラットフォームにワンクリックで展開可能。Nuxt.js、Vue 3、およびTailwind CSSを使用したフルスタック開発。組み込みのOpenAIプロキシにより、APIキーの安全性が保護されています。', 7 | ogDescription: 8 | 'SwiftSoraを使用して簡単に動画や画像を生成しましょう。これはOpenAIの強力なSoraモデルを使用したオープンソースプロジェクトです。Vercelなどのプラットフォームにワンクリックで展開可能。Nuxt.js、Vue 3、およびTailwind CSSを使用したフルスタック開発。組み込みのOpenAIプロキシにより、APIキーの安全性が保護されています。', 9 | keywords: 'AI,AIGC,OpenAI,Sora,ビデオジェネレーター,SwiftSora', 10 | }, 11 | error: { 12 | e404: { 13 | title: 'ページが見つかりません', 14 | desc: 'おっと!おそらく誤ったリンクにアクセスしました。これが私たちの問題だと思われる場合は、お知らせください。', 15 | link: '', 16 | desc2: '', 17 | }, 18 | e500: { 19 | title: '重大なエラーが発生しました', 20 | desc: '今はコーヒーを飲む良いタイミングです。コーヒーを飲み終わったら、サービスを回復します。', 21 | link: '', 22 | desc2: '', 23 | }, 24 | e502: { 25 | title: 'メンテナンス中', 26 | desc: 'ご不便をおかけして申し訳ありませんが、現在メンテナンス作業を行っています。必要であれば、いつでも', 27 | link: 'お問い合わせ', 28 | desc2: 'していただくか、しばらくお待ちいただければサービスを再開します!', 29 | }, 30 | video_not_supported: 'お使いのブラウザはビデオタグをサポートしていません。', 31 | validation: { 32 | video_gen: { 33 | error1: 'プロンプトを入力してください', 34 | error2: '画像をアップロードしてください', 35 | }, 36 | }, 37 | }, 38 | common: { 39 | loading: '読み込み中...', 40 | read_more: '詳細を読む', 41 | go_home: 'ホームに戻る', 42 | }, 43 | site_nav: { 44 | tip: 'メインメニューを開く', 45 | video_gallery: 'ビデオギャラリー', 46 | blog: 'ブログ', 47 | gen_video: 'さあ!ビデオを作成しよう', 48 | }, 49 | lang_theme: { 50 | tip: 'ダークモードを切り替える', 51 | }, 52 | site_footer: { 53 | intro: 'SwiftSoraはオープンソースプロジェクトで、ユーザーがテキストのヒントからビデオを生成できるようにします。このプロジェクトはOpenAIのSoraモデルを使用してビデオ作成を簡素化し、ワンクリックのウェブサイトデプロイ機能を備えています。', 54 | about: '私たちについて', 55 | blog: 'ブログ', 56 | faq: 'よくある質問', 57 | docs: 'ドキュメント', 58 | contact: 'お問い合わせ', 59 | stay_tuned: 'お楽しみに!', 60 | discord: 'Discord', 61 | twitter: 'Twitter', 62 | github: 'Github', 63 | youtube: 'YouTubeコミュニティ', 64 | legal: '法的声明', 65 | license: 'ライセンス(Apache 2.0)', 66 | dmca: 'DMCA', 67 | legal_notice: 'プライバシーポリシー', 68 | terms: '利用規約', 69 | cookie_policy: 'Cookieポリシー', 70 | rights: '全著作権所有。', 71 | }, 72 | app_nav: { 73 | tip: 'ユーザーメニューを開く', 74 | settings: 'システム設定', 75 | signout: 'ログアウト', 76 | }, 77 | app_sidebar: { 78 | home: 'ホーム', 79 | community_feed: 'コミュニティフィード', 80 | personal_feed: '個人作品', 81 | user_tools1: '私の', 82 | user_tools2: 'ツール', 83 | video_gen: 'ビデオ生成', 84 | docs: 'ドキュメント', 85 | faq: 'よくある質問とヘルプ', 86 | }, 87 | index: { 88 | title: '', 89 | intro1: 'あなたの', 90 | intro2: '創造力を解放する', 91 | intro3: '強力な', 92 | sub_intro: '品質、速さ、スタイルの一貫性を備えた非常に優れたビデオを生成します。', 93 | gen_video: 'さあ、ビデオを作成しましょう!', 94 | guide1: { 95 | title: 'Soraとは何ですか?', 96 | desc: 'Soraはテキスト命令に基づいてリアルで想像力豊かなシーンを作成できるAIモデルです。OpenAIによって訓練されています。', 97 | }, 98 | guide2: { 99 | title: 'SwiftSoraとは何ですか?', 100 | desc: 'OpenAIの強力なSoraモデルを使用したオープンソースプロジェクトです。フルスタックのNuxt.js、Vue 3、Tailwind CSSで構築されています。', 101 | }, 102 | guide3: { 103 | title: '素早いデプロイ', 104 | desc: 'Vercel、Netlifyなどへのワンクリックデプロイが簡単にできます。', 105 | }, 106 | guide4: { 107 | title: 'APIキーの保護', 108 | desc: '組み込みのOpenAIプロキシを使用してAPIキーを保護します。情報のセキュリティは完全にあなたのコントロールで、APIキーの漏洩やリスクを防ぎます。', 109 | }, 110 | toolkit: { 111 | title1: 'SwiftSora', 112 | title2: ' ツールキット ', 113 | menu1: { 114 | title: 'ビデオ生成', 115 | sub_title: 'ヒントワード/ビデオ/画像をビデオに変換', 116 | desc1: 117 | '当社のビデオおよび画像生成ツールを使用して、アイデアを新たな高みに押し上げます。それはあなたの考えを現実にするだけでなく、可能性の境界を再定義します。初心者でもエキスパートでも、具体的なニーズに合わせてカスタマイズできる直感的な設定を提供します。自然な言葉のヒント、テキスト、音声、画像、またはビデオを使用して、簡単にビデオと画像を生成します。', 118 | desc2: '卓越したシンプルさとパワフルな統合を体験し、各レベルのユーザーの創造的な思考に応えます。', 119 | }, 120 | menu2: { 121 | title: 'ビデオ編集', 122 | sub_title: 'ヒントワードを使用してビデオを編集', 123 | desc1: 'SwiftSoraはビジョンを実現するだけでなく、ビデオ操作のアートを再定義することでその能力を拡張します。直感的なコントロールを使用して、ビデオを簡単に編集、整理、変更し、初心者から経験豊富なプロまでが利益を得ることができます。', 124 | desc2: 'シームレスな共有を提供する当社のプラットフォームは、簡単で強力な完璧な融合を提供します。ビデオを強化、切り抜き、変換して、引き込まれるストーリーを作り出します。シームレスな組織、正確な変更、作品を簡単に共有できます。', 125 | }, 126 | menu3: { 127 | title: 'ビデオ認識', 128 | sub_title: 'ビデオをテキストに変換', 129 | desc1: 130 | '当社のビデオおよび画像生成ツールの革命的な能力を解放します。SwiftSoraは創造的なビデオ生成に限らず、ビデオの認識、処理、分析、理解を行う強力なツールです。初心者からエキスパートまでに合わせてカスタマイズされたこのツールは、直感的な設定を使用して限界を突破します。自然な言葉のヒント、テキスト、音声、画像に関係なく、シンプルで強力なシームレスな融合を体験できます。', 131 | desc2: '認識から生成までを簡単に行い、あらゆる創造的思考者にとって重要なツールにします。ニーズに合わせて適応するツールで競争力を向上させ、多機能かつ効率的な経験を提供します。', 132 | }, 133 | }, 134 | video_gallery: { 135 | title1: 'コミュニティ作品', 136 | title2: ' ギャラリー ', 137 | sub_title: 'SwiftSoraによって生成されたビデオ', 138 | more: '他のビデオ作品を見る', 139 | }, 140 | }, 141 | 142 | app: { 143 | index: { 144 | title: 'ホーム - アプリ', 145 | page_title: { 146 | pre: 'ここから', 147 | post: '始めましょう', 148 | }, 149 | get_start: { 150 | menu1: { 151 | title: 'ビデオ生成', 152 | desc: 'ヒントワード、ビデオ、画像などを使用してビデオを生成します。', 153 | }, 154 | menu2: { 155 | title: 'ビデオ編集', 156 | desc: '提供されたヒントワード、ビデオ、画像を使用してビデオを編集します。', 157 | }, 158 | menu3: { 159 | title: 'ビデオ認識', 160 | desc: 'ビデオを提出し、クリアで引き込まれるビデオの説明とヒントが自動生成されます。', 161 | }, 162 | }, 163 | page_title2: { 164 | pre: '最新', 165 | post: '作品', 166 | }, 167 | }, 168 | community_feed: { 169 | title: 'コミュニティフィード - アプリ', 170 | page_title: { 171 | pre: 'コミュニティ', 172 | post: 'フィード', 173 | sub: 'このページのすべてのビデオは、Soraによって直接生成され、修正されていません。', 174 | }, 175 | }, 176 | personal_feed: { 177 | title: '個人作品 - アプリ', 178 | page_title: { 179 | pre: '個人', 180 | post: '作品', 181 | sub: 'すべての作品はここに収められています。', 182 | }, 183 | }, 184 | video_gen: { 185 | title: 'ビデオ生成 - アプリ', 186 | load: { 187 | title: 'ビデオ生成中...', 188 | desc: '数分でビデオが準備されます', 189 | desc2: { 190 | pre: '生成されたビデオはあなたの', 191 | post: '個人作品', 192 | }, 193 | guide: { 194 | title: '待っている間に...', 195 | desc: '他のユーザーのクリエイションを見てみてください', 196 | }, 197 | }, 198 | text: { 199 | title: 'テキスト', 200 | guide: { 201 | title: 'テキストヒントワード', 202 | desc: 'テキストヒントワードを使用して画像を生成します。次に、画像を選択してビデオを生成します。', 203 | btn: '試してみる👉🏻例のヒントワード', 204 | }, 205 | aspect_ration: { 206 | title: 'アスペクト比', 207 | placeholder: '画像を説明するテキストヒントワードを入力してください。', 208 | }, 209 | style: { 210 | title: 'スタイル', 211 | video_styles: { 212 | none: 'デフォルト', 213 | _3d_model: '3Dモデル', 214 | analog_film: 'アナログフィルム', 215 | anime: 'アニメ', 216 | cinematic: '映画効果', 217 | comic_book: 'コミック', 218 | digital_art: 'デジタルアート', 219 | enhance: '強化', 220 | fantasy_art: 'ファンタジーアート', 221 | isometric: '等軸投影', 222 | line_art: '線画', 223 | low_poly: '低ポリゴン', 224 | modeling_compound: 'モデリング化合物', 225 | neon_punk: 'ネオンパンク', 226 | origami: '折り紙アート', 227 | photographic: '写真', 228 | pixel_art: 'ピクセルアート', 229 | tile_texture: 'タイルテクスチャ', 230 | }, 231 | }, 232 | }, 233 | image: { 234 | title: '画像', 235 | tip: '最適な効果を得るには、1024 × 576ピクセル、576 × 1024ピクセル、または768 × 768ピクセルの解像度の画像をアップロードしてください。', 236 | guide: { 237 | title: '画像アップロード', 238 | desc: 'ビデオを生成するために画像をアップロードします。', 239 | uploader: { 240 | title: { 241 | pre: 'クリックしてアップロード', 242 | post: 'またはドラッグアンドドロップ', 243 | }, 244 | supported_file: 'サポートされているファイルタイプ:PNG、JPG、またはGIF', 245 | }, 246 | }, 247 | }, 248 | btn_reset: 'リセット', 249 | btn_gen: '即座に生成', 250 | }, 251 | docs: { 252 | title: 'ドキュメント - アプリ', 253 | resources: { 254 | quickstart: { 255 | title: 'はじめに', 256 | desc: 'SwiftSoraの迅速な設定と展開方法を学びます。', 257 | }, 258 | github: { 259 | title: '気に入ったら星を付けてください!', 260 | desc: 'ソースコードは公式SwiftSora GitHubリポジトリからクローンまたはダウンロードできます。このプロジェクトが気に入った場合は、星をつけるのを忘れないでください。', 261 | }, 262 | contribution: { 263 | title: 'プロジェクトへの参加', 264 | desc: 'ローカルマシンでSwiftSoraに貢献し、開発を始める方法を学びます。', 265 | }, 266 | license: { 267 | title: 'ライセンス', 268 | desc: '私たちのオープンソースのイニシアティブは、革新、共有、コミュニティの発展を奨励しています。創造的な無限の世界に飛び込んでください。', 269 | }, 270 | blog: { 271 | title: 'ブログ', 272 | desc: '公式ブログでSwiftSoraに関するリソースやAIに関する知識をもっと見つけてください。', 273 | }, 274 | contact: { 275 | title: 'お問い合わせ', 276 | desc: 'いつでもDiscordコミュニティに参加し、SwiftSoraに関する質問をお気軽にお聞きください。', 277 | }, 278 | }, 279 | }, 280 | }, 281 | } 282 | -------------------------------------------------------------------------------- /lang/zh-CN.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | app_title: 'SwiftSora - AI视频生成器 - 通过文字生成视频和图片 | SwiftSora', 3 | seo: { 4 | ogTitle: 'SwiftSora - AI视频生成器 - 通过文字生成视频和图片 | SwiftSora', 5 | description: '使用SwiftSora轻松生成视频和图片,这是一个使用OpenAI强大Sora模型的开源项目。一键部署到Vercel等平台。采用Nuxt.js,Vue 3和Tailwind CSS全栈开发。通过内置的OpenAI代理保护您的API密钥的安全。', 6 | ogDescription: '使用SwiftSora轻松生成视频和图片,这是一个使用OpenAI强大Sora模型的开源项目。一键部署到Vercel等平台。采用Nuxt.js,Vue 3和Tailwind CSS全栈开发。通过内置的OpenAI代理保护您的API密钥的安全。', 7 | keywords: 'AI,AIGC,OpenAI,Sora,视频生成器,SwiftSora', 8 | }, 9 | error: { 10 | e404: { 11 | title: '页面未找到', 12 | desc: '哎呀!看起来您访问了一个错误的链接。如果您认为这是我们的问题,请告诉我们。', 13 | link: '', 14 | desc2: '', 15 | }, 16 | e500: { 17 | title: '发生了严重错误', 18 | desc: '现在是喝咖啡的好时机。我们会在您喝完咖啡的时候恢复服务。', 19 | link: '', 20 | desc2: '', 21 | }, 22 | e502: { 23 | title: '维护中', 24 | desc: '抱歉给您带来不便,我们目前正在进行一些维护工作。如果需要,您可以随时', 25 | link: '联系我们', 26 | desc2: ',否则我们将很快恢复服务!', 27 | }, 28 | video_not_supported: '您的浏览器不支持视频标签。', 29 | validation: { 30 | video_gen: { 31 | error1: '请输入提示词', 32 | error2: '请上传一张图片', 33 | }, 34 | }, 35 | }, 36 | common: { 37 | loading: '加载中...', 38 | read_more: '了解更多', 39 | go_home: '返回首页', 40 | }, 41 | site_nav: { 42 | tip: '打开主菜单', 43 | video_gallery: '视频作品展示', 44 | blog: '博客', 45 | gen_video: '来吧!动手创建一个视频', 46 | }, 47 | lang_theme: { 48 | tip: '切换深色主题', 49 | }, 50 | site_footer: { 51 | intro: 'SwiftSora是一个开源项目,允许用户在线从提示词生成视频。该项目利用OpenAI的Sora模型简化视频创建,包含一键网站部署功能,轻松便捷。', 52 | about: '关于我们', 53 | blog: '博客', 54 | faq: '常见问题', 55 | docs: '文档', 56 | contact: '联系我们', 57 | stay_tuned: '敬请关注!', 58 | discord: 'Discord', 59 | twitter: 'Twitter', 60 | github: 'Github', 61 | youtube: 'YouTube社区', 62 | legal: '法律声明', 63 | license: '许可证(Apache 2.0)', 64 | dmca: 'DMCA', 65 | legal_notice: '隐私政策', 66 | terms: '服务条款', 67 | cookie_policy: 'Cookie政策', 68 | rights: '保留所有权利。', 69 | }, 70 | app_nav: { 71 | tip: '打开用户菜单', 72 | settings: '系统设置', 73 | signout: '退出登录', 74 | }, 75 | app_sidebar: { 76 | home: '主页', 77 | community_feed: '社区动态', 78 | personal_feed: '个人作品', 79 | user_tools1: '我的', 80 | user_tools2: '工具', 81 | video_gen: '视频生成', 82 | docs: '文档', 83 | faq: '常见问题与帮助', 84 | }, 85 | index: { 86 | title: '', 87 | intro1: '释放您的', 88 | intro2: '创造力', 89 | intro3: '借助强大的', 90 | sub_intro: '为您生成质量、速度和风格的一致性无与伦比的的视频。', 91 | gen_video: '来吧!动手创建一个视频', 92 | guide1: { 93 | title: 'Sora是什么?', 94 | desc: 'Sora是一种能够根据文本指令创建逼真和富有想象力场景的AI大模型,由OpenAI训练。', 95 | }, 96 | guide2: { 97 | title: 'SwiftSora是什么?', 98 | desc: '一个使用OpenAI强大的Sora模型的开源项目。采用全栈Nuxt.js, Vue 3和Tailwind CSS构建。', 99 | }, 100 | guide3: { 101 | title: '快速部署', 102 | desc: '轻松一键部署到Vercel、Netlify和其他平台。', 103 | }, 104 | guide4: { 105 | title: '保护您的API密钥', 106 | desc: '使用内置的OpenAI代理保护您的API密钥。信息安全全部由您自己掌控,避免API Key泄露和风控。', 107 | }, 108 | toolkit: { 109 | title1: 'SwiftSora', 110 | title2: ' 工具包 ', 111 | menu1: { 112 | title: '视频生成', 113 | sub_title: '提示词/视频/图像转视频', 114 | desc1: '使用我们的视频和图像生成工具将您的创造力提升到新的高度。它不仅仅是将您的想法变为现实;它重新定义了可能性的边界。无论您是新手还是专家,我们提供一系列直观的设置,可根据您的具体需求进行定制。使用自然语言提示词、文本、语音、图像或视频轻松生成视频和图像。', 115 | desc2: '体验无与伦比的简单与实力的完美融合,精心打造,以满足各个水平用户的创造性思维。', 116 | }, 117 | menu2: { 118 | title: '视频编辑', 119 | sub_title: '使用提示词编辑您的视频', 120 | desc1: 'SwiftSora不仅将您的愿景带到现实,还通过重新定义视频操作的艺术来扩展其能力。使用直观的控制轻松编辑、组织和修改视频,使新手和经验丰富的专业人士都能受益。', 121 | desc2: '从轻松传输到流畅共享,我们的平台提供了简单和强大完美融合的体验。通过增强、裁剪和转换视频,打造引人入胜的叙事。无缝组织,精确修改,轻松分享您的创作。', 122 | }, 123 | menu3: { 124 | title: '视频识别', 125 | sub_title: '视频转文字', 126 | desc1: '释放我们的视频和图像生成工具的革命性能力 – 不仅限于创造性视频生成,SwiftSora更是视频识别、处理、分析、理解的强大工具。为初学者和专家量身定制,该工具通过直观的设置突破了界限。无论是自然语言提示词、文本、语音还是图像,都能体验简单和强大的无缝融合。', 127 | desc2: '轻松穿越识别到生成,使其成为每个创意思维者的重要工具。用一个能够适应您需求的工具提升您的竞争力,提供无与伦比的多功能和效率。', 128 | }, 129 | }, 130 | video_gallery: { 131 | title1: '社区作品', 132 | title2: ' 展示 ', 133 | sub_title: '由SwiftSora生成的视频', 134 | more: '查看更多视频作品', 135 | }, 136 | }, 137 | 138 | app: { 139 | index: { 140 | title: '主页 - 应用', 141 | page_title: { 142 | pre: '从这里 ', 143 | post: '开始', 144 | }, 145 | get_start: { 146 | menu1: { 147 | title: '视频生成', 148 | desc: '使用提示词、视频、图像等生成视频。', 149 | }, 150 | menu2: { 151 | title: '视频编辑', 152 | desc: '使用提供的提示词、视频、图像编辑视频。', 153 | }, 154 | menu3: { 155 | title: '视频识别', 156 | desc: '提交您的视频,自动生成清晰、引人入胜的视频描述和提示。', 157 | }, 158 | }, 159 | page_title2: { 160 | pre: '最新 ', 161 | post: '作品', 162 | }, 163 | }, 164 | community_feed: { 165 | title: '社区动态 - 应用', 166 | page_title: { 167 | pre: '社区 ', 168 | post: '动态', 169 | sub: '此页面上的所有视频均由Sora直接生成,没有进行修改。', 170 | }, 171 | }, 172 | personal_feed: { 173 | title: '个人作品 - 应用', 174 | page_title: { 175 | pre: '个人 ', 176 | post: '作品', 177 | sub: '您的全部作品都收录在这里。', 178 | }, 179 | }, 180 | video_gen: { 181 | title: '视频生成 - 应用', 182 | load: { 183 | title: '正在生成视频...', 184 | desc: '您的视频将在几分钟内准备就绪', 185 | desc2: { 186 | pre: '生成的视频将保存到您的', 187 | post: '个人作品', 188 | }, 189 | guide: { 190 | title: '在您等待期间不妨...', 191 | desc: '看看其他用户的创作', 192 | }, 193 | }, 194 | text: { 195 | title: '文本', 196 | guide: { 197 | title: '文本提示词', 198 | desc: '使用文本提示词生成图像。接下来,您将选择一张图像生成视频。', 199 | btn: '试一试👉🏻示例提示词', 200 | }, 201 | aspect_ration: { 202 | title: '画面比例', 203 | placeholder: '输入文本提示词,描述您的图像。', 204 | }, 205 | style: { 206 | title: '风格', 207 | video_styles: { 208 | none: '默认', 209 | _3d_model: '3D 模型', 210 | analog_film: '模拟胶片', 211 | anime: '动漫', 212 | cinematic: '电影效果', 213 | comic_book: '漫画', 214 | digital_art: '数字艺术', 215 | enhance: '增强', 216 | fantasy_art: '奇幻艺术', 217 | isometric: '等轴测图', 218 | line_art: '线描', 219 | low_poly: '低多边形', 220 | modeling_compound: '建模化合物', 221 | neon_punk: '霓虹朋克', 222 | origami: '折纸艺术', 223 | photographic: '摄影', 224 | pixel_art: '像素艺术', 225 | tile_texture: '瓷砖纹理', 226 | }, 227 | }, 228 | }, 229 | image: { 230 | title: '图像', 231 | tip: '为获得最佳效果,请上传分辨率为 1024 × 576像素、576 × 1024像素 或 768 × 768像素 的图像。', 232 | guide: { 233 | title: '图像上传', 234 | desc: '上传图像以生成视频。', 235 | uploader: { 236 | title: { 237 | pre: '点击上传', 238 | post: ' 或拖放', 239 | }, 240 | supported_file: '支持的文件类型:PNG、JPG 或 GIF', 241 | }, 242 | }, 243 | }, 244 | btn_reset: '重置', 245 | btn_gen: '立刻生成', 246 | }, 247 | docs: { 248 | title: '文档 - 应用', 249 | resources: { 250 | quickstart: { 251 | title: '开始使用', 252 | desc: '了解如何快速配置和部署 SwiftSora。', 253 | }, 254 | github: { 255 | title: '喜欢吗?给个星星吧!', 256 | desc: '源代码可从官方 SwiftSora GitHub 存储库克隆或下载。如果你喜欢这个项目,请别忘了给它点个星。', 257 | }, 258 | contribution: { 259 | title: '参与到项目', 260 | desc: '学习如何在本地机器上贡献 SwiftSora 并开始开发。', 261 | }, 262 | license: { 263 | title: '许可证', 264 | desc: '我们的开源倡议鼓励创新、共享和社区发展。进入一个创意无限的世界吧。', 265 | }, 266 | blog: { 267 | title: '博客', 268 | desc: '在我们的官方博客上发现更多有关 SwiftSora 的资源以及AI的相关知识。', 269 | }, 270 | contact: { 271 | title: '联系我们', 272 | desc: '随时加入 Discord 社区,并向我们咨询有关 SwiftSora 的任何问题。', 273 | }, 274 | }, 275 | }, 276 | }, 277 | } 278 | -------------------------------------------------------------------------------- /layouts/application.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 168 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 26 | -------------------------------------------------------------------------------- /nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | modules: ['@nuxtjs/tailwindcss', 'nuxt-icon', '@nuxt/image', '@nuxtjs/i18n', '@nuxt/content'], 4 | devtools: { 5 | enabled: true, 6 | timeline: { 7 | enabled: true, 8 | }, 9 | }, 10 | pages: true, 11 | i18n: { 12 | baseUrl: process.env.OPENAI_API_PROXY_URL || 'http://localhost:3000', 13 | vueI18n: './i18n.config.ts', 14 | locales: [ 15 | // 'en', 'en-US', 'ko-KR', 'ja-JP', 'zh-CN', 'zh-TW' 16 | { 17 | code: 'en-US', 18 | name: 'English (US)', 19 | iso: 'en-US', 20 | dir: 'ltr', 21 | file: 'en-US.ts', // add file name for each locale 22 | }, 23 | { 24 | code: 'ja-JP', 25 | name: '日本語', 26 | iso: 'ja-JP', 27 | dir: 'ltr', 28 | file: 'ja-JP.ts', 29 | }, 30 | { 31 | code: 'zh-CN', 32 | name: '中文 (简体)', 33 | iso: 'zh-CN', 34 | dir: 'ltr', 35 | file: 'zh-CN.ts', 36 | }, 37 | ], 38 | strategy: 'prefix', 39 | defaultLocale: 'en-US', 40 | detectBrowserLanguage: false, 41 | lazy: true, 42 | langDir: 'lang', 43 | }, 44 | content: { 45 | defaultLocale: 'en-US', 46 | documentDriven: false, 47 | locales: ['en-US', 'zh-CN', 'ja-JP'], 48 | }, 49 | tailwindcss: { 50 | cssPath: '~/assets/css/main.css', 51 | }, 52 | css: ['mosha-vue-toastify/dist/style.css'], 53 | app: { 54 | head: { 55 | charset: 'utf-8', 56 | viewport: 'width=device-width, initial-scale=1', 57 | }, 58 | }, 59 | runtimeConfig: { 60 | OPENAI_API_KEY: process.env.OPENAI_API_KEY || 'sk-xxxxxxxxxxxxxxxxxxxxxxxxxx', 61 | OPENAI_API_MODEL: process.env.OPENAI_API_MODEL || 'sora-1.0-turbo', 62 | OPENAI_API_BASE_URL: process.env.OPENAI_API_BASE_URL || 'https://api.openai.com', 63 | OPENAI_API_PROXY_URL: process.env.OPENAI_API_PROXY_URL || 'http://localhost:3000', 64 | }, 65 | routeRules: { 66 | '/': { prerender: true, redirect: '/en-US' }, 67 | '/legal-notice': { prerender: true }, 68 | '/terms-of-service': { prerender: true }, 69 | '/dmca': { prerender: true }, 70 | '/cookie-policy': { prerender: true }, 71 | '/api/**': { cors: true }, 72 | '/v1/**': { cors: true }, 73 | '/fakeOpenAISoraAPI': { cors: true }, 74 | }, 75 | }) 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "swiftsora", 3 | "private": false, 4 | "type": "module", 5 | "contributors": [ 6 | "Jason Williams (https://twitter.com/swiftsora)" 7 | ], 8 | "author": "Jason Williams ", 9 | "scripts": { 10 | "lint": "eslint .", 11 | "lint:fix": "eslint . --fix", 12 | "build": "nuxt build", 13 | "dev": "nuxt dev --host", 14 | "generate": "nuxt generate", 15 | "preview": "nuxt preview", 16 | "postinstall": "nuxt prepare" 17 | }, 18 | "dependencies": { 19 | "flowbite": "^2.3.0", 20 | "mosha-vue-toastify": "^1.0.23", 21 | "nuxt": "^3.10.3", 22 | "vue": "^3.4.19", 23 | "vue-router": "^4.3.0" 24 | }, 25 | "devDependencies": { 26 | "@nuxt/content": "^2.12.0", 27 | "@nuxt/eslint-config": "^0.2.0", 28 | "@nuxt/image": "^1.3.0", 29 | "@nuxt/kit": "^3.10.3", 30 | "@nuxtjs/i18n": "^8.1.1", 31 | "@nuxtjs/tailwindcss": "^6.11.4", 32 | "eslint": "^8.57.0", 33 | "nuxt-icon": "^0.6.8" 34 | }, 35 | "resolutions": { 36 | "sharp": "0.32.6" 37 | }, 38 | "overrides": { 39 | "sharp": "0.32.6" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pages/app/Community-Feed.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 20 | -------------------------------------------------------------------------------- /pages/app/Help.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 34 | 35 | -------------------------------------------------------------------------------- /pages/app/Personal-Feed.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 20 | -------------------------------------------------------------------------------- /pages/app/docs/[...slug].vue: -------------------------------------------------------------------------------- 1 | 6 | 40 | -------------------------------------------------------------------------------- /pages/app/index.vue: -------------------------------------------------------------------------------- 1 | 60 | 61 | 78 | -------------------------------------------------------------------------------- /pages/cookie-policy.vue: -------------------------------------------------------------------------------- 1 | 155 | 174 | -------------------------------------------------------------------------------- /pages/dmca.vue: -------------------------------------------------------------------------------- 1 | 63 | 72 | -------------------------------------------------------------------------------- /pages/legal-notice.vue: -------------------------------------------------------------------------------- 1 | 137 | 138 | 147 | -------------------------------------------------------------------------------- /public/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/alipay.jpg -------------------------------------------------------------------------------- /public/bg.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/bg.webp -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/favicon.ico -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-Bold.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-BoldItalic.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-ExtraBold.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-ExtraLight.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-ExtraLightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-ExtraLightItalic.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-Italic.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-Italic[wght].woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-Italic[wght].woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-Light.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-LightItalic.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-Medium.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-MediumItalic.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-Regular.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-SemiBold.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /public/fonts/PlusJakartaSans[wght].woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/fonts/PlusJakartaSans[wght].woff2 -------------------------------------------------------------------------------- /public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 10 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /public/logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/logo.webp -------------------------------------------------------------------------------- /public/openai.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/profile.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/profile.webp -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: * 2 | Allow: * 3 | Disallow: /api 4 | Disallow: /api/ 5 | Disallow: /api* 6 | Disallow: /*/api 7 | Disallow: /*/api/ 8 | Disallow: /*/api* 9 | Disallow: /v1/* 10 | Disallow: /fakeOpenAISoraAPI* -------------------------------------------------------------------------------- /public/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | https://www.swiftsora.com/en-US 12 | 2024-03-16T04:02:29+00:00 13 | 1.00 14 | 15 | 16 | https://www.swiftsora.com/en-US/app/community-feed 17 | 2024-03-16T04:02:29+00:00 18 | 0.80 19 | 20 | 21 | https://www.swiftsora.com/en-US/app/video-generation 22 | 2024-03-16T04:02:29+00:00 23 | 0.80 24 | 25 | 26 | https://www.swiftsora.com/en-US/app/docs 27 | 2024-03-16T04:02:29+00:00 28 | 0.80 29 | 30 | 31 | https://www.swiftsora.com/en-US/dmca 32 | 2024-03-16T04:02:29+00:00 33 | 0.80 34 | 35 | 36 | https://www.swiftsora.com/en-US/legal-notice 37 | 2024-03-16T04:02:29+00:00 38 | 0.80 39 | 40 | 41 | https://www.swiftsora.com/en-US/terms-of-service 42 | 2024-03-16T04:02:29+00:00 43 | 0.80 44 | 45 | 46 | https://www.swiftsora.com/en-US/cookie-policy 47 | 2024-03-16T04:02:29+00:00 48 | 0.80 49 | 50 | 51 | https://www.swiftsora.com/en-US/app 52 | 2024-03-16T04:02:29+00:00 53 | 0.64 54 | 55 | 56 | https://www.swiftsora.com/en-US/app/personal-feed 57 | 2024-03-16T04:02:29+00:00 58 | 0.64 59 | 60 | 61 | https://www.swiftsora.com/ja-JP 62 | 2024-03-16T04:03:54+00:00 63 | 1.00 64 | 65 | 66 | https://www.swiftsora.com/ja-JP/app/community-feed 67 | 2024-03-16T04:03:54+00:00 68 | 0.80 69 | 70 | 71 | https://www.swiftsora.com/ja-JP/app/video-generation 72 | 2024-03-16T04:03:54+00:00 73 | 0.80 74 | 75 | 76 | https://www.swiftsora.com/ja-JP/app/docs 77 | 2024-03-16T04:03:54+00:00 78 | 0.80 79 | 80 | 81 | https://www.swiftsora.com/ja-JP/dmca 82 | 2024-03-16T04:03:54+00:00 83 | 0.80 84 | 85 | 86 | https://www.swiftsora.com/ja-JP/legal-notice 87 | 2024-03-16T04:03:54+00:00 88 | 0.80 89 | 90 | 91 | https://www.swiftsora.com/ja-JP/terms-of-service 92 | 2024-03-16T04:03:54+00:00 93 | 0.80 94 | 95 | 96 | https://www.swiftsora.com/ja-JP/cookie-policy 97 | 2024-03-16T04:03:54+00:00 98 | 0.80 99 | 100 | 101 | https://www.swiftsora.com/ja-JP/app 102 | 2024-03-16T04:03:54+00:00 103 | 0.64 104 | 105 | 106 | https://www.swiftsora.com/ja-JP/app/personal-feed 107 | 2024-03-16T04:03:54+00:00 108 | 0.64 109 | 110 | 111 | https://www.swiftsora.com/zh-CN 112 | 2024-03-16T04:03:23+00:00 113 | 1.00 114 | 115 | 116 | https://www.swiftsora.com/zh-CN/app/community-feed 117 | 2024-03-16T04:03:23+00:00 118 | 0.80 119 | 120 | 121 | https://www.swiftsora.com/zh-CN/app/video-generation 122 | 2024-03-16T04:03:23+00:00 123 | 0.80 124 | 125 | 126 | https://www.swiftsora.com/zh-CN/app/docs 127 | 2024-03-16T04:03:23+00:00 128 | 0.80 129 | 130 | 131 | https://www.swiftsora.com/zh-CN/dmca 132 | 2024-03-16T04:03:23+00:00 133 | 0.80 134 | 135 | 136 | https://www.swiftsora.com/zh-CN/legal-notice 137 | 2024-03-16T04:03:23+00:00 138 | 0.80 139 | 140 | 141 | https://www.swiftsora.com/zh-CN/terms-of-service 142 | 2024-03-16T04:03:23+00:00 143 | 0.80 144 | 145 | 146 | https://www.swiftsora.com/zh-CN/cookie-policy 147 | 2024-03-16T04:03:23+00:00 148 | 0.80 149 | 150 | 151 | https://www.swiftsora.com/zh-CN/app 152 | 2024-03-16T04:03:23+00:00 153 | 0.64 154 | 155 | 156 | https://www.swiftsora.com/zh-CN/app/personal-feed 157 | 2024-03-16T04:03:23+00:00 158 | 0.64 159 | 160 | 161 | -------------------------------------------------------------------------------- /public/vercel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/vercel.png -------------------------------------------------------------------------------- /public/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonwang178/SwiftSora/9515bbde676de64207a82528f80e5808c0b8205a/public/wechat.jpg -------------------------------------------------------------------------------- /server/api/videos/generation.post.ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(async event => { 2 | const { OPENAI_API_KEY, OPENAI_API_MODEL, OPENAI_API_PROXY_URL } = useRuntimeConfig() 3 | 4 | const { prompt, aspect_ratio, style, type } = await readBody(event) 5 | try { 6 | let errorResp = {} 7 | if (type === 'txt' && !prompt) { 8 | errorResp = { 9 | error: { 10 | message: "You didn't provide a Prompt.", 11 | type: 'invalid_request_error', 12 | param: null, 13 | code: null, 14 | }, 15 | } 16 | setResponseStatus(event, 403) 17 | return errorResp 18 | } 19 | 20 | const data = await $fetch(`${OPENAI_API_PROXY_URL}/v1/video/generations`, { 21 | method: 'POST', 22 | headers: { 23 | Authorization: `Bearer ${OPENAI_API_KEY}`, 24 | }, 25 | body: { 26 | prompt, 27 | model: OPENAI_API_MODEL, 28 | aspect_ratio, 29 | style, 30 | type, 31 | }, 32 | }) 33 | return { 34 | toJSON() { 35 | // @ts-ignore 36 | return data?.data 37 | }, 38 | } 39 | } catch (error) { 40 | console.error(error.data) 41 | setResponseStatus(event, 500) 42 | return error.data 43 | } 44 | }) 45 | -------------------------------------------------------------------------------- /server/api/videos/index.get.ts: -------------------------------------------------------------------------------- 1 | import { Video } from '~/server/models/Video' 2 | //@ts-ignore 3 | import { listVideos } from '~/server/services/videoService' 4 | 5 | export default defineEventHandler(async event => { 6 | const params = getQuery(event) 7 | let c: any = params.c 8 | let r: any = params.r 9 | let count: number = -1 10 | let random: boolean = true 11 | 12 | if (c) count = parseInt(c) 13 | if (r && r === '0') random = false 14 | 15 | const videos:Video[] = await listVideos(count, random) 16 | // appendHeader(event, 'Content-Type', 'application/json') 17 | 18 | const data = { 19 | createdAt: new Date(), 20 | toJSON() { 21 | return videos 22 | }, 23 | } 24 | 25 | return data 26 | }) 27 | -------------------------------------------------------------------------------- /server/models/Video.ts: -------------------------------------------------------------------------------- 1 | export interface Video { 2 | id: string 3 | prompt: string 4 | url: string 5 | keywords: [] 6 | aspect_ratio: string 7 | width: string 8 | height: string 9 | fps: string 10 | thumbnail_url: string 11 | author: string 12 | author_img: string 13 | created_at: string 14 | } 15 | -------------------------------------------------------------------------------- /server/routes/fakeOpenAISoraAPI.post.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Video } from '~/server/models/Video' 3 | // @ts-ignore 4 | import { cherryPickOneVideo } from '~/server/services/videoService' 5 | 6 | export default defineEventHandler(async event => { 7 | /** 8 | * // TODO WARNING!!! 9 | * This is a fake OpenAI Sora API. Please deactivate the code on production once the official Sora API becomes available. 10 | * You need to substitute the code with an actual OpenAI API call and create the corresponding return value. 11 | */ 12 | // const url = getRequestURL(event) 13 | const headers = getHeaders(event) 14 | // const clientIP = headers['x-forwarded-for'] 15 | 16 | const bearer = headers['authorization'] 17 | const apiKey = bearer?.replace('Bearer ', '') 18 | 19 | const body = await readBody(event) 20 | 21 | const model = body.model?.trim() 22 | const prompt = body.prompt?.trim() 23 | const aspect_ratio = body.aspect_ratio 24 | const style = body.style 25 | const type = body.type 26 | 27 | let errorResp = null 28 | 29 | if (!bearer) { 30 | errorResp = { 31 | error: { 32 | message: 33 | "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. You can obtain an API key from https://platform.openai.com/account/api-keys.", 34 | type: 'invalid_request_error', 35 | param: null, 36 | code: null, 37 | }, 38 | } 39 | setResponseStatus(event, 401) 40 | return errorResp 41 | } 42 | 43 | if (!apiKey || apiKey === 'Bearer') { 44 | errorResp = { 45 | error: { 46 | message: 47 | "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. You can obtain an API key from https://platform.openai.com/account/api-keys.", 48 | type: 'invalid_request_error', 49 | param: null, 50 | code: null, 51 | }, 52 | } 53 | setResponseStatus(event, 401) 54 | return errorResp 55 | } 56 | 57 | if (!model) { 58 | errorResp = { 59 | error: { 60 | message: 'Invalid model', 61 | type: 'invalid_request_error', 62 | param: null, 63 | code: null, 64 | }, 65 | } 66 | setResponseStatus(event, 403) 67 | return errorResp 68 | } 69 | 70 | if (!type) { 71 | errorResp = { 72 | error: { 73 | message: "You didn't provide a Type.", 74 | type: 'invalid_request_error', 75 | param: null, 76 | code: null, 77 | }, 78 | } 79 | setResponseStatus(event, 403) 80 | return errorResp 81 | } 82 | 83 | if (type === 'txt' && !prompt) { 84 | errorResp = { 85 | error: { 86 | message: "You didn't provide a Prompt.", 87 | type: 'invalid_request_error', 88 | param: null, 89 | code: null, 90 | }, 91 | } 92 | setResponseStatus(event, 403) 93 | return errorResp 94 | } 95 | const { aspect_ratios } = useAppConfig() 96 | if (!aspect_ratio || !aspect_ratios.includes(aspect_ratio)) { 97 | errorResp = { 98 | error: { 99 | message: `${aspect_ratio} is not one of ['1:1', '16:9', '9:16'] - 'aspect_ratio'`, 100 | type: 'invalid_request_error', 101 | param: null, 102 | code: null, 103 | }, 104 | } 105 | setResponseStatus(event, 403) 106 | return errorResp 107 | } 108 | const { video_styles } = useAppConfig() 109 | if (!style || !video_styles.hasOwnProperty(style)) { 110 | errorResp = { 111 | error: { 112 | message: `${style} is not valid - 'style'`, 113 | type: 'invalid_request_error', 114 | param: null, 115 | code: null, 116 | }, 117 | } 118 | setResponseStatus(event, 403) 119 | return errorResp 120 | } 121 | 122 | // @ts-ignore 123 | const video: Video = type === 'txt' ? await cherryPickOneVideo(prompt) : await cherryPickOneVideo() 124 | 125 | const resp = { 126 | data: { 127 | toJSON() { 128 | return video 129 | }, 130 | }, 131 | } 132 | 133 | return resp 134 | }) 135 | -------------------------------------------------------------------------------- /server/routes/v1/[...].ts: -------------------------------------------------------------------------------- 1 | export default defineEventHandler(async event => { 2 | const { OPENAI_API_PROXY_URL, OPENAI_API_BASE_URL } = useRuntimeConfig() 3 | const headers = getHeaders(event) 4 | let url = getRequestURL(event) 5 | const req = toWebRequest(event) 6 | const method = req.method 7 | try { 8 | const headers_clone = JSON.parse(JSON.stringify(headers)) 9 | Object.keys(headers_clone).forEach(key => { 10 | if (key.toLowerCase().startsWith('x-')) { 11 | delete headers_clone[key] 12 | } 13 | }) 14 | if (headers_clone.hasOwnProperty('content-length')) { 15 | delete headers_clone['content-length'] 16 | } 17 | headers_clone.host = new URL(OPENAI_API_BASE_URL).host 18 | 19 | let targetURL: string = '' 20 | // TODO: Please comment and deactive the following lines of code (between BEGIN and END) when the official Sora API becomes accessible. 21 | // -------- BEGIN 22 | if (url.pathname === '/v1/video/generations') { 23 | targetURL = `${OPENAI_API_PROXY_URL}/fakeOpenAISoraAPI` 24 | } else { 25 | targetURL = `${OPENAI_API_BASE_URL}${url.pathname}` 26 | } 27 | // -------- END 28 | 29 | 30 | // TODO: Please uncomment the following line of code when the official Sora API becomes accessible. 31 | // targetURL = `${OPENAI_API_BASE_URL}${url.pathname}` 32 | 33 | const opt = { 34 | method, 35 | headers: headers_clone, 36 | } 37 | 38 | let body = undefined 39 | let query = undefined 40 | if (['POST', 'PUT'].includes(method)) { 41 | body = await readBody(event) 42 | // @ts-ignore 43 | if (body) opt.body = body 44 | } 45 | query = getQuery(event) 46 | // @ts-ignore 47 | if (query) opt.query = query 48 | 49 | // @ts-ignore 50 | return await $fetch(targetURL, opt) 51 | } catch (error) { 52 | console.error(error) 53 | setResponseStatus(event, error.statusCode) 54 | return error.data 55 | } 56 | }) 57 | -------------------------------------------------------------------------------- /server/services/videoService.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { Video } from '~/server/models/Video' 3 | 4 | export const listVideos = async (count: number, random: boolean = true) => { 5 | // TODO: 6 | // 1. Retrieve video metadata from the database (e.g., PostgreSQL, MongoDB, MySQL). 7 | // 2. Fetch the video from server-side storage, such as AWS S3. 8 | // 3. Pagination 9 | 10 | // @ts-ignore 11 | const data: any = await import('~/server/data/sora_videos.json') 12 | let videos: Video[] = data.default 13 | 14 | let rand_nums: number[] = [] 15 | let random_videos: Video[] = [] 16 | let size = count > 0 ? count : videos.length 17 | 18 | if (random) { 19 | while (rand_nums.length < size) { 20 | let rn: number = Math.floor(Math.random() * videos.length) 21 | if (!rand_nums.includes(rn)) { 22 | rand_nums.push(rn) 23 | // if (videos[rn] === undefined || videos[rn] === null) { 24 | // } 25 | random_videos.push(videos[rn]) 26 | } 27 | } 28 | } else { 29 | random_videos = videos 30 | } 31 | 32 | if (count > 0) { 33 | if (random_videos) { 34 | return random_videos?.slice(0, count) 35 | } 36 | return {} 37 | } 38 | 39 | return random_videos 40 | } 41 | 42 | export const getOneRandomVideo = (videos: Video[]) => { 43 | let rn: number = Math.floor(Math.random() * videos.length) 44 | return videos[rn] 45 | } 46 | 47 | export const cherryPickOneVideo = async (prompt: string) => { 48 | let hitVideo: Video | undefined = undefined 49 | 50 | // @ts-ignore 51 | const data: any = await import('~/server/data/sora_videos.json') 52 | let videos: Video[] = data.default 53 | if (prompt) { 54 | const countOccurrences: Function = (arr, target) => arr.reduce((count, item) => (item === target ? count + 1 : count), 0) 55 | 56 | const inputTexts: string[] = prompt.split(' ') 57 | let occurrences: number = 0 58 | videos.forEach(video => { 59 | const videoTexts: string[] = video.prompt.split(' ') 60 | let currentOccurrences: number = 0 61 | 62 | inputTexts.forEach(t => { 63 | currentOccurrences = countOccurrences(videoTexts, t) 64 | }) 65 | 66 | if (currentOccurrences > occurrences) { 67 | occurrences = currentOccurrences 68 | hitVideo = video 69 | } 70 | }) 71 | 72 | if (occurrences == 0) { 73 | hitVideo = getOneRandomVideo(videos) 74 | } 75 | } else { 76 | hitVideo = getOneRandomVideo(videos) 77 | } 78 | 79 | return hitVideo 80 | } 81 | -------------------------------------------------------------------------------- /server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ['./app.vue', './error.vue', './components/**/*.{js,vue,ts}', './layouts/**/*.vue', './pages/**/*.vue', './plugins/**/*.{js,ts}', './nuxt.config.{js,ts}', './node_modules/flowbite/**/*.{js,ts}'], 3 | theme: { 4 | extend: { 5 | colors: { 6 | // primary: { 50: '#eff6ff', 100: '#dbeafe', 200: '#bfdbfe', 300: '#93c5fd', 400: '#60a5fa', 500: '#3b82f6', 600: '#2563eb', 700: '#1d4ed8', 800: '#1e40af', 900: '#1e3a8a' }, 7 | primary: { 50: '#f5f3ff', 100: '#ede9fe', 200: '#ddd6fe', 300: '#c4b5fd', 400: '#a78bfa', 500: '#8b5cf6', 600: '#7c3aed', 700: '#6d28d9', 800: '#5b21b6', 900: '#4c1d95' }, 8 | }, 9 | fontFamily: { 10 | sans: ['"Plus Jakarta Sans"', 'Inter', 'ui-sans-serif', 'system-ui', '-apple-system', 'system-ui', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'Noto Sans', 'sans-serif', 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'], 11 | body: ['"Plus Jakarta Sans"', 'Inter', 'ui-sans-serif', 'system-ui', '-apple-system', 'system-ui', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'Noto Sans', 'sans-serif', 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'], 12 | mono: ['ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', 'monospace'], 13 | }, 14 | transitionProperty: { 15 | width: 'width', 16 | }, 17 | textDecoration: ['active'], 18 | minWidth: { 19 | kanban: '28rem', 20 | }, 21 | }, 22 | }, 23 | darkMode: 'class', 24 | safelist: ['w-64', 'w-1/2', 'rounded-l-lg', 'rounded-r-lg', 'bg-gray-200', 'grid-cols-4', 'grid-cols-7', 'h-6', 'leading-6', 'h-9', 'leading-9', 'shadow-lg'], 25 | plugins: [ 26 | require('flowbite'), 27 | // plugin(function ({ matchUtilities, theme }) { 28 | // matchUtilities( 29 | // { 30 | // 'aside-scrollbars': value => { 31 | // const track = value === 'light' ? '100' : '900' 32 | // const thumb = value === 'light' ? '300' : '600' 33 | // const color = value === 'light' ? 'gray' : value 34 | 35 | // return { 36 | // scrollbarWidth: 'thin', 37 | // scrollbarColor: `${theme(`colors.${color}.${thumb}`)} ${theme(`colors.${color}.${track}`)}`, 38 | // '&::-webkit-scrollbar': { 39 | // width: '8px', 40 | // height: '8px', 41 | // }, 42 | // '&::-webkit-scrollbar-track': { 43 | // backgroundColor: theme(`colors.${color}.${track}`), 44 | // }, 45 | // '&::-webkit-scrollbar-thumb': { 46 | // borderRadius: '0.25rem', 47 | // backgroundColor: theme(`colors.${color}.${thumb}`), 48 | // }, 49 | // } 50 | // }, 51 | // }, 52 | // { values: theme('asideScrollbars') } 53 | // ) 54 | // }), 55 | ], 56 | } 57 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /utils/index.ts: -------------------------------------------------------------------------------- 1 | export const scrollToTop = () => { 2 | window.scrollTo({ 3 | top: 0, 4 | behavior: 'smooth', 5 | }) 6 | } 7 | -------------------------------------------------------------------------------- /utils/lang.ts: -------------------------------------------------------------------------------- 1 | export const localeName = (locCode: string) => { 2 | switch (locCode) { 3 | case 'en-US': 4 | return 'English (US)' 5 | case 'en': 6 | return 'English' 7 | case 'ko-KR': 8 | return '한국인' 9 | case 'ja-JP': 10 | return '日本語' 11 | case 'zh-CN': 12 | return '中文 (简体)' 13 | case 'zh-TW': 14 | return '中文 (繁體)' 15 | default: 16 | return 'English (US)' 17 | } 18 | return 'English (US)' 19 | } 20 | 21 | export const localeIcon = (locCode: string) => { 22 | switch (locCode) { 23 | case 'en-US': 24 | return 'emojione:flag-for-united-states' 25 | case 'en': 26 | return 'emojione:flag-for-united-states' 27 | case 'ko-KR': 28 | return 'emojione:flag-for-south-korea' 29 | case 'ja-JP': 30 | return 'emojione:flag-for-japan' 31 | case 'zh-CN': 32 | return 'emojione:flag-for-china' 33 | case 'zh-TW': 34 | return 'emojione:flag-for-hong-kong-sar-china' 35 | default: 36 | return 'emojione:flag-for-united-states' 37 | } 38 | return 'emojione:flag-for-united-states' 39 | } 40 | 41 | export const getLocaleVideoStyles = () => { 42 | const { t } = useI18n() 43 | const video_styles = [ 44 | { name: t('app.video_gen.text.style.video_styles.none'), value: 'none' }, 45 | { name: t('app.video_gen.text.style.video_styles.analog_film'), value: 'analog_film' }, 46 | { name: t('app.video_gen.text.style.video_styles.anime'), value: 'anime' }, 47 | { name: t('app.video_gen.text.style.video_styles.cinematic'), value: 'cinematic' }, 48 | { name: t('app.video_gen.text.style.video_styles.comic_book'), value: 'comic_book' }, 49 | { name: t('app.video_gen.text.style.video_styles.digital_art'), value: 'digital_art' }, 50 | { name: t('app.video_gen.text.style.video_styles.enhance'), value: 'enhance' }, 51 | { name: t('app.video_gen.text.style.video_styles.fantasy_art'), value: 'fantasy_art' }, 52 | { name: t('app.video_gen.text.style.video_styles.isometric'), value: 'isometric' }, 53 | { name: t('app.video_gen.text.style.video_styles.line_art'), value: 'line_art' }, 54 | { name: t('app.video_gen.text.style.video_styles.low_poly'), value: 'low_poly' }, 55 | { name: t('app.video_gen.text.style.video_styles.modeling_compound'), value: 'modeling_compound' }, 56 | { name: t('app.video_gen.text.style.video_styles.neon_punk'), value: 'neon_punk' }, 57 | { name: t('app.video_gen.text.style.video_styles.origami'), value: 'origami' }, 58 | { name: t('app.video_gen.text.style.video_styles.photographic'), value: 'photographic' }, 59 | { name: t('app.video_gen.text.style.video_styles.pixel_art'), value: 'pixel_art' }, 60 | { name: t('app.video_gen.text.style.video_styles.tile_texture'), value: 'tile_texture' }, 61 | ] 62 | 63 | return video_styles 64 | } 65 | 66 | export const getLocaleVideoStyle = (styleValue: string) => { 67 | const { t } = useI18n() 68 | return t(`app.video_gen.text.style.video_styles.${styleValue}`) 69 | } 70 | export const getOriPath = (path: string) => path.replace(/^\/[a-zA-Z-]+/, '') 71 | -------------------------------------------------------------------------------- /utils/theme.js: -------------------------------------------------------------------------------- 1 | export const setDarkMode = (payload = null) => { 2 | const appConfig = useAppConfig() 3 | const { darkModeKey } = appConfig 4 | const darkMode = useDarkMode() 5 | 6 | darkMode.value = payload !== null ? payload : !darkMode.value 7 | 8 | if (typeof localStorage !== 'undefined') { 9 | localStorage.setItem(darkModeKey, darkMode.value ? '1' : '0') 10 | } 11 | 12 | if (typeof document !== 'undefined') { 13 | document.body.classList[darkMode.value ? 'add' : 'remove']('dark') 14 | document.documentElement.classList[darkMode.value ? 'add' : 'remove']('dark') 15 | } 16 | } 17 | 18 | export const initTheme = () => { 19 | const { darkModeKey } = useAppConfig() 20 | if (localStorage.getItem(darkModeKey) === '1' || (!(darkModeKey in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) { 21 | document.documentElement.classList.add('dark') 22 | setDarkMode(true) 23 | } else { 24 | document.documentElement.classList.remove('dark') 25 | setDarkMode(false) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /utils/title.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns a full HTML title, appending the site name 3 | * to the page title given. 4 | * 5 | * @param pageTitle HTML title of the current page 6 | * @returns Full HTML title, including localized site name 7 | */ 8 | export const title = (pageTitle: string): string => { 9 | const { t } = useI18n() 10 | 11 | return `${pageTitle} | ${t('app_title')}` 12 | } 13 | 14 | /** 15 | * Returns a translated page HTML title. You must declare 16 | * the key/value pair in your translation messages. This 17 | * function appends the localized site name to the title. 18 | * 19 | * @param locKey translation key 20 | * @returns the localized HTML title, including site name 21 | */ 22 | export const localizedTitle = (locKey: string): string => { 23 | const { t } = useI18n() 24 | const localizedPageTitle = t(locKey) 25 | 26 | return title(localizedPageTitle) 27 | } 28 | --------------------------------------------------------------------------------