Compare commits

...

23 Commits
main ... dev

Author SHA1 Message Date
username
8f10c393d9 新增11.txt 2025-08-10 22:01:01 +08:00
username
9f2de912c2 Merge branch 'dev' of http://110.42.96.65:19890/GoCo/OL-LearnPlatform into dev 2025-08-04 02:17:52 +08:00
username
af756a13e2 第一版学生端页面 2025-08-04 02:13:12 +08:00
小张
e26dd38c46 面包屑 2025-08-02 21:57:44 +08:00
小张
44dd95a124 面包屑 2025-08-02 21:49:25 +08:00
小张
39baaf7ecc 我的下载和我的资料两个模块 2025-08-02 20:39:43 +08:00
小张
93bd6c330a 我的下载和我的资料两个模块 2025-08-02 18:52:31 +08:00
小张
7afd24e9a0 我的活动我的消息模块 2025-08-01 07:00:47 +08:00
小张
d8d388b437 个人中心框架和考试练习模块 2025-08-01 03:11:23 +08:00
username
5e6c8f708f 解决接口问题 2025-08-01 01:22:09 +08:00
username
80ee63236a 登录请求错误解决 2025-07-30 03:57:52 +08:00
username
4a2cacbd8f Merge branch 'dev' of http://110.42.96.65:19890/GoCo/OL-LearnPlatform into dev 2025-07-30 02:54:37 +08:00
username
d8cce4cb46 活动相关页面详情 2025-07-30 02:46:20 +08:00
小张
37fca451c1 个人中心框架和我的作业模块 2025-07-29 23:19:07 +08:00
username
ab31374e1a 修改课程播放视频代码 2025-07-29 16:04:50 +08:00
username
c7453da854 活动和精选资源以及师资力量页面的静态渲染 2025-07-29 00:06:54 +08:00
小张
5bb1bbac26 个人中心框架和我的课程模块 2025-07-28 23:29:50 +08:00
Lzh
0deadff2aa Merge pull request 'main' (#1) from main into dev
Reviewed-on: #1
2025-07-28 09:57:55 +08:00
GoCo
63a869a390 fix: 🐛 dockerfile文件权限修改 2025-07-22 17:56:19 +08:00
GoCo
1c3197b9d8 fix: 🐛 docker compose端口修改 2025-07-22 17:30:18 +08:00
GoCo
5103edf6e1 fix: 🐛 修改镜像端口 2025-07-22 17:15:34 +08:00
GoCo
8950c82884 fix: 🐛 更改镜像node版本 2025-07-22 17:01:30 +08:00
GoCo
e2443f4def feat: 🎸 dockerfile 2025-07-22 16:51:54 +08:00
135 changed files with 140461 additions and 2133 deletions

2
.env
View File

@ -1,5 +1,5 @@
# API配置
VITE_API_BASE_URL=http://110.42.96.65:55510/api
# Mock配置 - 切换到真实API
# Mock配置 - 禁用Mock使用真实API
VITE_ENABLE_MOCK=false

View File

@ -1,9 +1,9 @@
# 生产环境配置
# API配置
VITE_API_BASE_URL=http://110.42.86.55:5510/api
VITE_API_BASE_URL=http://110.42.96.65:55510/api
# Mock配置 - 生产环境禁用Mock
# Mock配置 - 生产环境禁用Mock使用真实API
VITE_ENABLE_MOCK=false
# 生产模式

1
11.txt Normal file
View File

@ -0,0 +1 @@
测试

15
Dockerfile Normal file
View File

@ -0,0 +1,15 @@
# 使用 node 构建阶段
FROM node:22 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
# 使用 nginx 作为生产环境
FROM nginx:stable-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
# 设置静态资源的访问权限,避免 403 Forbidden
RUN find /usr/share/nginx/html -type f -exec chmod 644 {} \; \
&& find /usr/share/nginx/html -type d -exec chmod 755 {} \;
COPY nginx.conf /etc/nginx/conf.d/default.conf

107
deploy.js Normal file
View File

@ -0,0 +1,107 @@
#!/usr/bin/env node
/**
* 部署脚本 - 自动配置环境变量和构建项目
*/
const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')
console.log('🚀 开始部署流程...')
// 检查是否有真实的API服务器
async function checkApiServer(apiUrl) {
try {
const fetch = (await import('node-fetch')).default
const response = await fetch(`${apiUrl}/health`, {
timeout: 5000,
method: 'GET'
})
return response.ok
} catch (error) {
console.log(`❌ API服务器检查失败: ${error.message}`)
return false
}
}
// 读取环境配置
function readEnvFile(filePath) {
if (!fs.existsSync(filePath)) {
return {}
}
const content = fs.readFileSync(filePath, 'utf8')
const env = {}
content.split('\n').forEach(line => {
const trimmed = line.trim()
if (trimmed && !trimmed.startsWith('#')) {
const [key, ...valueParts] = trimmed.split('=')
if (key && valueParts.length > 0) {
env[key.trim()] = valueParts.join('=').trim()
}
}
})
return env
}
// 写入环境配置
function writeEnvFile(filePath, env) {
const content = Object.entries(env)
.map(([key, value]) => `${key}=${value}`)
.join('\n')
fs.writeFileSync(filePath, content + '\n')
}
async function main() {
// 读取生产环境配置
const prodEnv = readEnvFile('.env.production')
const apiUrl = prodEnv.VITE_API_BASE_URL
if (apiUrl) {
console.log(`🔍 检查API服务器: ${apiUrl}`)
const isApiAvailable = await checkApiServer(apiUrl.replace('/api', ''))
if (isApiAvailable) {
console.log('✅ API服务器可用使用真实API')
prodEnv.VITE_ENABLE_MOCK = 'false'
} else {
console.log('❌ API服务器不可用启用Mock模式')
prodEnv.VITE_ENABLE_MOCK = 'true'
}
} else {
console.log('⚠️ 未配置API地址启用Mock模式')
prodEnv.VITE_ENABLE_MOCK = 'true'
}
// 更新生产环境配置
writeEnvFile('.env.production', prodEnv)
console.log('📝 已更新生产环境配置')
// 构建项目
console.log('🔨 开始构建项目...')
try {
execSync('npm run build', { stdio: 'inherit' })
console.log('✅ 构建完成!')
// 显示部署信息
console.log('\n📋 部署信息:')
console.log(` Mock模式: ${prodEnv.VITE_ENABLE_MOCK === 'true' ? '启用' : '禁用'}`)
if (apiUrl) {
console.log(` API地址: ${apiUrl}`)
}
console.log(' 构建文件: ./dist/')
} catch (error) {
console.error('❌ 构建失败:', error.message)
process.exit(1)
}
}
main().catch(error => {
console.error('❌ 部署失败:', error)
process.exit(1)
})

11
docker-compose.yaml Normal file
View File

@ -0,0 +1,11 @@
version: '3.8'
services:
vue-app:
build:
context: .
dockerfile: Dockerfile
ports:
- "55514:80"
container_name: vue3-nginx
restart: unless-stopped

View File

@ -8,9 +8,9 @@
<meta name="description" content="专业的在线学习平台,提供优质的编程和技术课程">
<meta name="keywords" content="在线学习,编程课程,技术培训,Vue.js,React,Node.js">
<!-- CKPlayer CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ckplayer@8.3.5/dist/ckplayer.css">
<link rel="stylesheet" href="/ckplayer/css/ckplayer.css">
<!-- CKPlayer JS -->
<script src="https://cdn.jsdelivr.net/npm/ckplayer@8.3.5/dist/ckplayer.js"></script>
<script src="/ckplayer/js/ckplayer.js"></script>
</head>
<body>
<div id="app"></div>

11
nginx.conf Normal file
View File

@ -0,0 +1,11 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}

7
package-lock.json generated
View File

@ -11,7 +11,6 @@
"@vicons/ionicons5": "^0.13.0",
"axios": "^1.11.0",
"ckplayer": "^3.1.2",
"hls.js": "^1.6.7",
"naive-ui": "^2.42.0",
"pinia": "^3.0.3",
"vue": "^3.5.17",
@ -2467,12 +2466,6 @@
"node": ">=12.0.0"
}
},
"node_modules/hls.js": {
"version": "1.6.7",
"resolved": "https://registry.npmmirror.com/hls.js/-/hls.js-1.6.7.tgz",
"integrity": "sha512-QW2fnwDGKGc9DwQUGLbmMOz8G48UZK7PVNJPcOUql1b8jubKx4/eMHNP5mGqr6tYlJNDG1g10Lx2U/qPzL6zwQ==",
"license": "Apache-2.0"
},
"node_modules/hookable": {
"version": "5.5.3",
"resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz",

View File

@ -6,14 +6,16 @@
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"build:prod": "node deploy.js",
"type-check": "vue-tsc --noEmit",
"preview": "vite preview"
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui"
},
"dependencies": {
"@vicons/ionicons5": "^0.13.0",
"axios": "^1.11.0",
"ckplayer": "^3.1.2",
"hls.js": "^1.6.7",
"naive-ui": "^2.42.0",
"pinia": "^3.0.3",
"vue": "^3.5.17",

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

202
public/ckplayer/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,104 @@
flv.js [![npm](https://img.shields.io/npm/v/flv.js.svg?style=flat)](https://www.npmjs.com/package/flv.js)
======
An HTML5 Flash Video (FLV) Player written in pure JavaScript without Flash. LONG LIVE FLV!
This project relies on [Media Source Extensions][] to work.
**For FLV live stream playback, please consider [mpegts.js][] which is under active development.**
**This project will become rarely maintained.**
[mpegts.js]: https://github.com/xqq/mpegts.js
## Overview
flv.js works by transmuxing FLV file stream into ISO BMFF (Fragmented MP4) segments, followed by feeding mp4 segments into an HTML5 `<video>` element through [Media Source Extensions][] API.
[Media Source Extensions]: https://w3c.github.io/media-source/
## Demo
[http://bilibili.github.io/flv.js/demo/](http://bilibili.github.io/flv.js/demo/)
## Features
- FLV container with H.264 + AAC / MP3 codec playback
- Multipart segmented video playback
- HTTP FLV low latency live stream playback
- FLV over WebSocket live stream playback
- Compatible with Chrome, FireFox, Safari 10, IE11 and Edge
- Extremely low overhead, and hardware accelerated by your browser!
## Installation
```bash
npm install --save flv.js
```
## Build
```bash
npm ci # install dependencies / dev-dependences
npm run build:debug # debug version flv.js will be emitted to /dist
npm run build # minimized release version flv.min.js will be emitted to /dist
```
[cnpm](https://github.com/cnpm/cnpm) mirror is recommended if you are in Mainland China.
## CORS
If you use standalone video server for FLV stream, `Access-Control-Allow-Origin` header must be configured correctly on video server for cross-origin resource fetching.
See [cors.md](docs/cors.md) for more details.
## Getting Started
```html
<script src="flv.min.js"></script>
<video id="videoElement"></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://example.com/flv/video.flv'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
```
## Limitations
- MP3 audio codec is currently not working on IE11 / Edge
- HTTP FLV live stream is not currently working on all browsers, see [livestream.md](docs/livestream.md)
## Multipart playback
You only have to provide a playlist for `MediaDataSource`. See [multipart.md](docs/multipart.md)
## Livestream playback
See [livestream.md](docs/livestream.md)
## API and Configuration
See [api.md](docs/api.md)
## Debug
```bash
npm ci # install dependencies / dev-dependences
npm run dev # watch file changes and build debug version on the fly
```
## Design
See [design.md](docs/design.md)
## License
```
Copyright (C) 2016 Bilibili. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```

10585
public/ckplayer/flv.js/flv.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

10
public/ckplayer/flv.js/flv.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,28 @@
Copyright (c) 2017 Dailymotion (http://www.dailymotion.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
src/remux/mp4-generator.js and src/demux/exp-golomb.ts implementation in this project
are derived from the HLS library for video.js (https://github.com/videojs/videojs-contrib-hls)
That work is also covered by the Apache 2 License, following copyright:
Copyright (c) 2013-2015 Brightcove
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,442 @@
[![npm](https://img.shields.io/npm/v/hls.js.svg?style=flat)](https://npmjs.org/package/hls.js)
[![npm](https://img.shields.io/npm/v/hls.js/canary.svg?style=flat)](https://www.npmjs.com/package/hls.js/v/canary)
[![](https://data.jsdelivr.com/v1/package/npm/hls.js/badge?style=rounded)](https://www.jsdelivr.com/package/npm/hls.js)
[![Sauce Test Status](https://saucelabs.com/buildstatus/robwalch)](https://app.saucelabs.com/u/robwalch)
[comment]: <> ([![Sauce Test Status]&#40;https://saucelabs.com/browser-matrix/robwalch.svg&#41;]&#40;https://saucelabs.com/u/robwalch&#41;)
# ![HLS.js](https://cloud.githubusercontent.com/assets/616833/19739063/e10be95a-9bb9-11e6-8100-2896f8500138.png)
HLS.js is a JavaScript library that implements an [HTTP Live Streaming] client.
It relies on [HTML5 video][] and [MediaSource Extensions][] for playback.
It works by transmuxing MPEG-2 Transport Stream and AAC/MP3 streams into ISO BMFF (MP4) fragments.
Transmuxing is performed asynchronously using a [Web Worker] when available in the browser.
HLS.js also supports HLS + fmp4, as announced during [WWDC2016](https://developer.apple.com/videos/play/wwdc2016/504/).
HLS.js works directly on top of a standard HTML`<video>` element.
HLS.js is written in [ECMAScript6] (`*.js`) and [TypeScript] (`*.ts`) (strongly typed superset of ES6), and transpiled in ECMAScript5 using [Babel](https://babeljs.io/) and the [TypeScript compiler].
[Webpack] is used to build the distro bundle and serve the local development environment.
[html5 video]: https://www.html5rocks.com/en/tutorials/video/basics/
[mediasource extensions]: https://w3c.github.io/media-source/
[http live streaming]: https://en.wikipedia.org/wiki/HTTP_Live_Streaming
[web worker]: https://caniuse.com/#search=worker
[ecmascript6]: https://github.com/ericdouglas/ES6-Learning#articles--tutorials
[typescript]: https://www.typescriptlang.org/
[typescript compiler]: https://www.typescriptlang.org/docs/handbook/compiler-options.html
[webpack]: https://webpack.js.org/
## Features
- VOD & Live playlists
- DVR support on Live playlists
- Fragmented MP4 container
- MPEG-2 TS container
- ITU-T Rec. H.264 and ISO/IEC 14496-10 Elementary Stream
- ISO/IEC 13818-7 ADTS AAC Elementary Stream
- ISO/IEC 11172-3 / ISO/IEC 13818-3 (MPEG-1/2 Audio Layer III) Elementary Stream
- Packetized metadata (ID3v2.3.0) Elementary Stream
- AAC container (audio only streams)
- MPEG Audio container (MPEG-1/2 Audio Layer III audio only streams)
- Timed Metadata for HTTP Live Streaming (in ID3 format, carried in MPEG-2 TS)
- AES-128 decryption
- SAMPLE-AES decryption (only supported if using MPEG-2 TS container)
- Encrypted media extensions (EME) support for DRM (digital rights management)
- Widevine CDM (only tested with [shaka-packager](https://github.com/google/shaka-packager) test-stream on [the demo page](https://hls-js.netlify.app/demo/?src=https%3A%2F%2Fstorage.googleapis.com%2Fshaka-demo-assets%2Fangel-one-widevine-hls%2Fhls.m3u8&demoConfig=eyJlbmFibGVTdHJlYW1pbmciOnRydWUsImF1dG9SZWNvdmVyRXJyb3IiOnRydWUsInN0b3BPblN0YWxsIjpmYWxzZSwiZHVtcGZNUDQiOmZhbHNlLCJsZXZlbENhcHBpbmciOi0xLCJsaW1pdE1ldHJpY3MiOi0xfQ==))
- CEA-608/708 captions
- WebVTT subtitles
- Alternate Audio Track Rendition (Master Playlist with Alternative Audio) for VoD and Live playlists
- Adaptive streaming
- Manual & Auto Quality Switching
- 3 Quality Switching modes are available (controllable through API means)
- Instant switching (immediate quality switch at current video position)
- Smooth switching (quality switch for next loaded fragment)
- Bandwidth conservative switching (quality switch change for next loaded fragment, without flushing the buffer)
- In Auto-Quality mode, emergency switch down in case bandwidth is suddenly dropping to minimize buffering.
- Accurate Seeking on VoD & Live (not limited to fragment or keyframe boundary)
- Ability to seek in buffer and back buffer without redownloading segments
- Built-in Analytics
- All internal events can be monitored (Network Events, Video Events)
- Playback session metrics are also exposed
- Resilience to errors
- Retry mechanism embedded in the library
- Recovery actions can be triggered fix fatal media or network errors
- [Redundant/Failover Playlists](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/UsingHTTPLiveStreaming/UsingHTTPLiveStreaming.html#//apple_ref/doc/uid/TP40008332-CH102-SW22)
### Supported M3U8 tags
For details on the HLS format and these tags' meanings, see https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08
#### Manifest tags
- `#EXT-X-STREAM-INF:<attribute-list>`
`<URI>`
- `#EXT-X-MEDIA:<attribute-list>`
- `#EXT-X-SESSION-DATA:<attribute-list>`
The following properties are added to their respective variants' attribute list but are not implemented in their selection and playback.
- `VIDEO-RANGE` and `HDCP-LEVEL` (See [#2489](https://github.com/video-dev/hls.js/issues/2489))
#### Playlist tags
- `#EXTM3U`
- `#EXT-X-VERSION=<n>`
- `#EXTINF:<duration>,[<title>]`
- `#EXT-X-ENDLIST`
- `#EXT-X-MEDIA-SEQUENCE=<n>`
- `#EXT-X-TARGETDURATION=<n>`
- `#EXT-X-DISCONTINUITY`
- `#EXT-X-DISCONTINUITY-SEQUENCE=<n>`
- `#EXT-X-BYTERANGE=<n>[@<o>]`
- `#EXT-X-MAP:<attribute-list>`
- `#EXT-X-KEY:<attribute-list>` (`METHOD=SAMPLE-AES` is only supports with MPEG-2 TS segments)
- `#EXT-X-PROGRAM-DATE-TIME:<attribute-list>`
- `#EXT-X-START:TIME-OFFSET=<n>`
- `#EXT-X-SERVER-CONTROL:<attribute-list>`
- `#EXT-X-PART-INF:PART-TARGET=<n>`
- `#EXT-X-PART:<attribute-list>`
- `#EXT-X-PRELOAD-HINT:<attribute-list>`
- `#EXT-X-SKIP:<attribute-list>`
- `#EXT-X-RENDITION-REPORT:<attribute-list>`
The following tags are added to their respective fragment's attribute list but are not implemented in streaming and playback.
- `#EXT-X-DATERANGE:<attribute-list>` (Not added to metadata TextTracks. See [#2218](https://github.com/video-dev/hls.js/issues/2218))
- `#EXT-X-BITRATE` (Not used in ABR controller)
- `#EXT-X-GAP` (Not implemented. See [#2940](https://github.com/video-dev/hls.js/issues/2940))
### Not Supported
For a complete list of issues, see ["Top priorities" in the Release Planning and Backlog project tab](https://github.com/video-dev/hls.js/projects/6). Codec support is dependent on the runtime environment (for example, not all browsers on the same OS support HEVC).
- CMAF CC support [#2623](https://github.com/video-dev/hls.js/issues/2623)
- `Emsg` Inband Timed Metadata for FMP4 (ID3 within Emsgv1) in "metadata" TextTracks [#2360](https://github.com/video-dev/hls.js/issues/2360)
- `#EXT-X-DATERANGE` in "metadata" TextTracks [#2218](https://github.com/video-dev/hls.js/issues/2218)
- `#EXT-X-GAP` filling [#2940](https://github.com/video-dev/hls.js/issues/2940)
- `#EXT-X-I-FRAME-STREAM-INF` I-frame Media Playlist files
- `SAMPLE-AES` with fmp4, aac, mp3, vtt... segments (MPEG-2 TS only)
- PlayReady and FairPlay DRM ( See [#3779](https://github.com/video-dev/hls.js/issues/2360) and [issues labeled DRM](https://github.com/video-dev/hls.js/issues?q=is%3Aissue+is%3Aopen+label%3ADRM))
- Advanced variant selection based on runtime media capabilities (See issues labeled [`media-capabilities`](https://github.com/video-dev/hls.js/labels/media-capabilities))
- MP3 elementary stream audio in IE and Edge (<=18) on Windows 10 (See [#1641](https://github.com/video-dev/hls.js/issues/1641) and [Microsoft answers forum](https://answers.microsoft.com/en-us/ie/forum/all/ie11-on-windows-10-cannot-play-hls-with-mp3/2da994b5-8dec-4ae9-9201-7d138ede49d9))
### Server-side-rendering (SSR) and `require` from a Node.js runtime
You can safely require this library in Node and **absolutely nothing will happen**. A dummy object is exported so that requiring the library does not throw an error. HLS.js is not instantiable in Node.js. See [#1841](https://github.com/video-dev/hls.js/pull/1841) for more details.
## Getting started with development
First, checkout the repository and install the required dependencies
```sh
git clone https://github.com/video-dev/hls.js.git
cd hls.js
# After cloning or pulling from the repository, make sure all dependencies are up-to-date
npm install ci
# Run dev-server for demo page (recompiles on file-watch, but doesn't write to actual dist fs artifacts)
npm run dev
# After making changes run the sanity-check task to verify all checks before committing changes
npm run sanity-check
```
The dev server will host files on port 8000. Once started, the demo can be found running at http://localhost:8000/demo/.
Before submitting a PR, please see our [contribution guidelines](CONTRIBUTING.md).
Join the discussion on Slack via [video-dev.org](https://video-dev.org) in #hlsjs for updates and questions about development.
### Build tasks
Build all flavors (suitable for prod-mode/CI):
```
npm install ci
npm run build
```
Only debug-mode artifacts:
```
npm run build:debug
```
Build and watch (customized dev setups where you'll want to host through another server than webpacks' - for example in a sub-module/project)
```
npm run build:watch
```
Only specific flavor (known configs are: debug, dist, light, light-dist, demo):
```
npm run build -- --env dist # replace "dist" by other configuration name, see above ^
```
Note: The "demo" config is always built.
**NOTE:** `hls.light.*.js` dist files do not include EME, subtitles, CMCD, or alternate-audio support. In addition,
the following types are not available in the light build:
- `AudioStreamController`
- `AudioTrackController`
- `CuesInterface`
- `EMEController`
- `SubtitleStreamController`
- `SubtitleTrackController`
- `TimelineController`
- `CmcdController`
### Linter (ESlint)
Run linter:
```
npm run lint
```
Run linter with auto-fix mode:
```
npm run lint:fix
```
Run linter with errors only (no warnings)
```
npm run lint:quiet
```
### Formatting Code
Run prettier to format code
```
npm run prettier
```
### Type Check
Run type-check to verify TypeScript types
```
npm run type-check
```
### Automated tests (Mocha/Karma)
Run all tests at once:
```
npm test
```
Run unit tests:
```
npm run test:unit
```
Run unit tests in watch mode:
```
npm run test:unit:watch
```
Run functional (integration) tests:
```
npm run test:func
```
## Design
An overview of this project's design, it's modules, events, and error handling can be found [here](/docs/design.md).
## API docs and usage guide
- [API and usage docs, with code examples](./docs/API.md)
- [Auto-Generated API Docs (Latest Release)](https://hls-js.netlify.com/api-docs)
- [Auto-Generated API Docs (Development Branch)](https://hls-js-dev.netlify.com/api-docs)
_Note you can access the docs for a particular version using "[https://github.com/video-dev/hls.js/tree/deployments](https://github.com/video-dev/hls.js/tree/deployments)"_
## Demo
### Latest Release
[https://hls-js.netlify.com/demo](https://hls-js.netlify.com/demo)
### Master
[https://hls-js-dev.netlify.com/demo](https://hls-js-dev.netlify.com/demo)
### Specific Version
Find the commit on [https://github.com/video-dev/hls.js/tree/deployments](https://github.com/video-dev/hls.js/tree/deployments).
[![](https://www.netlify.com/img/global/badges/netlify-color-accent.svg)](https://www.netlify.com)
[![](https://opensource.saucelabs.com/images/opensauce/powered-by-saucelabs-badge-gray.png?sanitize=true)](https://saucelabs.com)
## Compatibility
HLS.js is only compatible with browsers supporting MediaSource extensions (MSE) API with 'video/MP4' mime-type inputs.
HLS.js is supported on:
- Chrome 39+ for Android
- Chrome 39+ for Desktop
- Firefox 41+ for Android
- Firefox 42+ for Desktop
- IE11 for Windows 8.1+
- Edge for Windows 10+
- Safari 8+ for MacOS 10.10+
- Safari for ipadOS 13+
A [Promise polyfill](https://github.com/taylorhakes/promise-polyfill) is required in browsers missing native promise support.
**Please note:** iOS Safari on iPhone does not support the MediaSource API. This includes all browsers on iOS as well as apps using UIWebView and WKWebView.
Safari browsers (iOS, iPadOS, and macOS) have built-in HLS support through the plain video "tag" source URL. See the example below (Using HLS.js) to run appropriate feature detection and choose between using HLS.js or natively built-in HLS support.
When a platform has neither MediaSource nor native HLS support, the browser cannot play HLS.
_Keep in mind that if the intention is to support HLS on multiple platforms, beyond those compatible with HLS.js, the HLS streams need to strictly follow the specifications of RFC8216, especially if apps, smart TVs, and set-top boxes are to be supported._
Find a support matrix of the MediaSource API here: https://developer.mozilla.org/en-US/docs/Web/API/MediaSource
## Using HLS.js
### Installation
Prepackaged builds are included [with each release](https://github.com/video-dev/hls.js/releases). Or install the hls.js as a dependency
of your project:
```sh
npm install --save hls.js
```
A canary channel is also available if you prefer to work off the development branch (master):
```
npm install hls.js@canary
```
### Embedding HLS.js
Directly include dist/hls.js or dist/hls.min.js in a script tag on the page. This setup prioritizes HLS.js MSE playback over
native browser support for HLS playback in HTMLMediaElements:
```html
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<!-- Or if you want a more recent alpha version -->
<!-- <script src="https://cdn.jsdelivr.net/npm/hls.js@alpha"></script> -->
<video id="video"></video>
<script>
var video = document.getElementById('video');
var videoSrc = 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8';
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(videoSrc);
hls.attachMedia(video);
}
// HLS.js is not supported on platforms that do not have Media Source
// Extensions (MSE) enabled.
//
// When the browser has built-in HLS support (check using `canPlayType`),
// we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video
// element through the `src` property. This is using the built-in support
// of the plain video element, without using HLS.js.
//
// Note: it would be more normal to wait on the 'canplay' event below however
// on Safari (where you are most likely to find built-in HLS support) the
// video.src URL must be on the user-driven white-list before a 'canplay'
// event will be emitted; the last video event that can be reliably
// listened-for when the URL is not on the white-list is 'loadedmetadata'.
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = videoSrc;
}
</script>
```
#### Alternative setup
To check for native browser support first and then fallback to HLS.js, swap these conditionals. See [this comment](https://github.com/video-dev/hls.js/pull/2954#issuecomment-670021358) to understand some of the tradeoffs.
```html
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<!-- Or if you want a more recent alpha version -->
<!-- <script src="https://cdn.jsdelivr.net/npm/hls.js@alpha"></script> -->
<video id="video"></video>
<script>
var video = document.getElementById('video');
var videoSrc = 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8';
//
// First check for native browser HLS support
//
if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = videoSrc;
//
// If no native HLS support, check if HLS.js is supported
//
} else if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(videoSrc);
hls.attachMedia(video);
}
</script>
```
For more embed and API examples see [docs/API.md](./docs/API.md).
## CORS
All HLS resources must be delivered with [CORS headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) permitting `GET` requests.
## Video Control
Video is controlled through HTML `<video>` element `HTMLVideoElement` methods, events and optional UI controls (`<video controls>`).
## Player Integration
The following players integrate HLS.js for HLS playback:
- [JW Player](https://www.jwplayer.com)
- [Akamai Adaptive Media Player (AMP)](https://www.akamai.com/us/en/solutions/products/media-delivery/adaptive-media-player.jsp)
- [Clappr](https://github.com/clappr/clappr)
- [Flowplayer](https://www.flowplayer.org) through [flowplayer-hlsjs](https://github.com/flowplayer/flowplayer-hlsjs)
- [MediaElement.js](https://www.mediaelementjs.com)
- [Videojs](https://videojs.com) through [Videojs-hlsjs](https://github.com/benjipott/videojs-hlsjs)
- [Videojs](https://videojs.com) through [videojs-hls.js](https://github.com/streamroot/videojs-hls.js). hls.js is integrated as a SourceHandler -- new feature in Video.js 5.
- [Videojs](https://videojs.com) through [videojs-contrib-hls.js](https://github.com/Peer5/videojs-contrib-hls.js). Production ready plug-in with full fallback compatibility built-in.
- [Fluid Player](https://www.fluidplayer.com)
- [OpenPlayerJS](https://www.openplayerjs.com), as part of the [OpenPlayer project](https://github.com/openplayerjs)
- [CDNBye](https://github.com/cdnbye/hlsjs-p2p-engine), a p2p engine for hls.js powered by WebRTC Datachannel.
### They use HLS.js in production!
| | | | |
| :----------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| [<img src="https://i.cdn.turner.com/adultswim/big/img/global/adultswim.jpg" width="120">](https://www.adultswim.com/streams) | [<img src="https://avatars3.githubusercontent.com/u/5497190?s=200&v=4" width="120">](https://www.akamai.com) | [<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Canal%2B.svg/2000px-Canal%2B.svg.png" width="120">](https://www.canalplus.fr) | [<img src="https://avatars2.githubusercontent.com/u/115313" width="120">](https://www.dailymotion.com) |
| [<img src="https://user-images.githubusercontent.com/4006693/44003595-baff193c-9e8f-11e8-9848-7bb91563499f.png" width="120">](https://freshlive.tv) | [<img src="https://flowplayer.org/media/img/logo-blue.png" width="120">](https://flowplayer.com) | [<img src="https://avatars1.githubusercontent.com/u/12554082?s=240" width="120">](https://www.foxsports.com.au) | [<img src="https://cloud.githubusercontent.com/assets/244265/12556435/dfaceb48-c353-11e5-971b-2c4429725469.png" width="120">](https://www.globo.com) |
| [<img src="https://images.gunosy.com/logo/gunosy_icon_company_logo.png" width="120">](https://gunosy.com) | [<img src="https://user-images.githubusercontent.com/1480052/35802840-f8e85b8a-0a71-11e8-8eb2-eee323e3f159.png" width="120">](https://www.gl-systemhaus.de/) | [<img src="https://cloud.githubusercontent.com/assets/6525783/20801836/700490de-b7ea-11e6-82bd-e249f91c7bae.jpg" width="120">](https://nettrek.de) | [<img src="https://cloud.githubusercontent.com/assets/244265/12556385/999aa884-c353-11e5-9102-79df54384498.png" width="120">](https://www.nytimes.com/) |
| [<img src="https://cloud.githubusercontent.com/assets/1798553/20356424/ba158574-ac24-11e6-95e1-1ae591b11a0a.png" width="120">](https://www.peer5.com/) | [<img src="https://cloud.githubusercontent.com/assets/4909096/20925062/e26e6fc8-bbb4-11e6-99a5-d4762274a342.png" width="120">](https://www.qbrick.com) | [<img src="https://www.radiantmediaplayer.com/images/radiantmediaplayer-new-logo-640.jpg" width="120">](https://www.radiantmediaplayer.com/) | [<img src="https://www.rts.ch/hummingbird-static/images/logos/logo_marts.svg" width="120">](https://www.rts.ch) |
| [<img src="https://cloud.githubusercontent.com/assets/12702747/19316434/0a3601de-9067-11e6-85e2-936b1cb099a0.png" width="120">](https://www.snapstream.com/) | [<img src="https://pamediagroup.com/wp-content/uploads/2019/05/StreamAMG-Logo-RGB.png" width="120">](https://www.streamamg.com/) | [<img src="https://streamsharkio.sa.metacdn.com/wp-content/uploads/2015/10/streamshark-dark.svg" width="120">](https://streamshark.io/) | [<img src="https://camo.githubusercontent.com/9580f10e9bfa8aa7fba52c5cb447bee0757e33da/68747470733a2f2f7777772e7461626c6f74762e636f6d2f7374617469632f696d616765732f7461626c6f5f6c6f676f2e706e67" width="120">](https://my.tablotv.com/) |
| [<img src="https://user-images.githubusercontent.com/2803310/34083705-349c8fd0-e375-11e7-92a6-5c38509f4936.png" width="120">](https://www.streamroot.io/) | [<img src="https://vignette1.wikia.nocookie.net/tedtalks/images/c/c0/TED_logo.png/revision/20150915192527" width="120">](https://www.ted.com/) | [<img src="https://www.seeklogo.net/wp-content/uploads/2014/12/twitter-logo-vector-download.jpg" width="120">](https://twitter.com/) | [<img src="https://player.clevercast.com/img/clevercast.png" width="120">](https://www.clevercast.com) |
| [<img src="https://player.mtvnservices.com/edge/hosted/Viacom_logo.svg" width="120">](https://www.viacom.com/) | [<img src="https://user-images.githubusercontent.com/1181974/29248959-efabc440-802d-11e7-8050-7c1f4ca6c607.png" width="120">](https://vk.com/) | [<img src="https://avatars0.githubusercontent.com/u/5090060?s=200&v=4" width="120">](https://www.jwplayer.com) | [<img src="https://staticftv-a.akamaihd.net/arches/francetv/default/img/og-image.jpg?20161007" width="120">](https://www.france.tv) |
| [<img src="https://showmax.akamaized.net/e/logo/showmax_black.png" width="120">](https://tech.showmax.com) | [<img src="https://static3.1tv.ru/assets/web/logo-ac67852f1625b338f9d1fb96be089d03557d50bfc5790d5f48dc56799f59dec6.svg" width="120" height="120">](https://www.1tv.ru/) | [<img src="https://user-images.githubusercontent.com/1480052/40482633-c013ebce-5f55-11e8-96d5-b776415de0ce.png" width="120">](https://www.zdf.de) | [<img src="https://github.com/cdnbye/hlsjs-p2p-engine/blob/master/figs/cdnbye.png" width="120">](https://github.com/cdnbye/hlsjs-p2p-engine) |
| [cdn77](https://streaming.cdn77.com/) | [<img src="https://avatars0.githubusercontent.com/u/7442371?s=200&v=4" width="120">](https://r7.com/) | [<img src="https://raw.githubusercontent.com/Novage/p2p-media-loader/gh-pages/images/p2pml-logo.png" width="120">](https://github.com/Novage/p2p-media-loader) | [<img src="https://avatars3.githubusercontent.com/u/45617200?s=400" width="120">](https://kayosports.com.au) |
| [<img src="https://avatars1.githubusercontent.com/u/5279615?s=400&u=9771a216836c613f1edf4afe71cfc69d4c5657ed&v=4" width="120">](https://flosports.tv) | [<img src="https://www.logolynx.com/images/logolynx/c6/c67a2cb3ad33a82b5518f8ad8f124703.png" width="120">](https://global.axon.com/) | | |
## Chrome/Firefox integration
made by [gramk](https://github.com/gramk/chrome-hls), plays hls from address bar and m3u8 links
- Chrome [native-hls](https://chrome.google.com/webstore/detail/native-hls-playback/emnphkkblegpebimobpbekeedfgemhof)
- Firefox [native-hls](https://addons.mozilla.org/en-US/firefox/addon/native_hls_playback/)
## License
HLS.js is released under [Apache 2.0 License](LICENSE)

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

27804
public/ckplayer/hls.js/hls.js Normal file

File diff suppressed because it is too large Load Diff

2837
public/ckplayer/hls.js/hls.js.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
public/ckplayer/hls.js/hls.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

7
public/ckplayer/js/ckplayer.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,72 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.ckplayerLanguage = factory());
}(this, function () { 'use strict';
/*
* 功能包含播放器用到的全部相关语言文字
*/
var language={
play:'Play',
pause:'Pause',
refresh:'Refresh',
full:'Fullscreen',
exitFull:'Non-Fullscreen',
webFull:'Web fullscreen',
exitWebFull:'Non-Web fullscreen',
theatre:'Theatre',
exitTheatre:'Non-theatre',
volume:'Volume',
muted:'Mute',
exitmuted:'Unmute',
seek:'Seek',
waiting:'Waiting',
live:'Liveing',
backLive:'Back live',
lookBack:'Look back',
next:'Next episode',
screenshot:'Screenshot',
smallwindows:'Small windows',
playbackrate:'Speed',
playbackrateSuffix:' Speed',
track:'Subtitle',
noTrack:'No subtitle',
definition:'Definition',
switchTo:'Switched from',
closeTime:'The advertisement can be closed in {seconds} seconds',
closeAd:'Close ad',
second:'seconds',
details:'View details',
copy:'Copy',
copySucceeded:'Copy succeeded, can be pasted!',
smallwindowsOpen:'The small window function is turned on',
screenshotStart:'Screenshot, please wait...',
smallwindowsClose:'The small window function is turned off',
screenshotClose:'Screenshot function is turned off',
loopOpen:'Loop open',
loopClose:'Loop close',
close:'Close',
down:'Down',
p50:'50%',
p75:'75%',
p100:'100%',
timeScheduleAdjust:{
prohibit:'No dragging',
prohibitBackOff:'No repeat viewing',
prohibitForward:'Fast forward prohibited',
prohibitLookBack:'Some content is forbidden to play',
prohibitForwardNotViewed:'Disable playback of parts not viewed'
},
error:{
noMessage:'Unknown error',
supportVideoError:'The browser version is too low. It is recommended to replace it with another browser',
videoTypeError:'This browser does not support playing this video. It is recommended to replace it with another browser',
loadingFailed:'Loading failed',
emptied:'An error occurred while loading the frequency file',
screenshot:'Screenshot failed',
ajax:'Ajax data request error',
noVideoContainer:'No video container'
}
};
return language;
}))

View File

@ -0,0 +1,72 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.ckplayerLanguage = factory());
}(this, function () { 'use strict';
/*
* 功能包含播放器用到的全部相关语言文字
*/
var language={
play:'播放',
pause:'暂停',
refresh:'重播',
full:'全屏',
exitFull:'退出全屏',
webFull:'页面全屏',
exitWebFull:'退出页面全屏',
theatre:'剧场模式',
exitTheatre:'退出剧场模式',
volume:'音量:',
muted:'静音',
exitmuted:'恢复音量',
seek:'seek',
waiting:'缓冲',
live:'直播中',
backLive:'返回直播',
lookBack:'回看:',
next:'下一集',
screenshot:'视频截图',
smallwindows:'小窗口播放功能',
playbackrate:'倍速',
playbackrateSuffix:'倍',
track:'字幕',
noTrack:'无字幕',
definition:'清晰度',
switchTo:'切换成:',
closeTime:'{seconds}秒后可关闭广告',
closeAd:'关闭广告',
second:'秒',
details:'查看详情',
copy:'复制',
copySucceeded:'复制成功,可贴粘!',
smallwindowsOpen:'小窗口功能已开启',
smallwindowsClose:'小窗口功能已关闭',
screenshotStart:'截图中,请稍候...',
screenshotClose:'截图功能已关闭',
loopOpen:'循环播放',
loopClose:'已关闭循环播放',
close:'关闭',
down:'下载',
p50:'50%',
p75:'75%',
p100:'100%',
timeScheduleAdjust:{
prohibit:'视频禁止拖动',
prohibitBackOff:'视频禁止重复观看',
prohibitForward:'视频禁止快进',
prohibitLookBack:'视频禁止播放部分内容',
prohibitForwardNotViewed:'视频禁止播放未观看的部分'
},
error:{
noMessage:'未知错误',
supportVideoError:'该浏览器版本太低,建议更换成其它浏览器',
videoTypeError:'该浏览器不支持播放该视频,建议更换成其它浏览器',
loadingFailed:'加载失败',
emptied:'视频文件加载过程中出现错误',
screenshot:'视频截图失败',
ajax:'Ajax数据请求错误',
noVideoContainer:'未找到放置视频的容器'
}
};
return language;
}))

View File

@ -0,0 +1,72 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.ckplayerLanguage = factory());
}(this, function () { 'use strict';
/*
*功能包含播放機用到的全部相關語言文字
*/
var language = {
play: '播放',
pause: '暫停',
refresh: '重播',
full: '全屏',
exitFull: '退出全屏',
webFull: '頁面全屏',
exitWebFull: '退出頁面全屏',
theatre: '劇場模式',
exitTheatre: '退出劇場模式',
volume: '音量:',
muted: '靜音',
exitmuted: '恢復音量',
seek: 'seek:',
waiting: '緩衝',
live: '直播中',
backLive: '返回直播',
lookBack: '回看:',
next: '下一集',
screenshot: '視頻截圖',
smallwindows: '小視窗播放功能',
playbackrate: '倍速',
playbackrateSuffix: '倍',
track: '字幕',
noTrack: '無字幕',
definition: '清晰度',
switchTo: '切換成:',
closeTime: '{seconds}秒後可關閉廣告',
closeAd: '關閉廣告',
second: '秒',
details: '查看詳情',
copy: '複製',
copySucceeded: '複製成功,可貼粘!',
smallwindowsOpen: '小視窗功能已開啟',
smallwindowsClose: '小視窗功能已關閉',
screenshotStart: '截圖中,請稍候…',
screenshotClose: '截圖功能已關閉',
loopOpen: '迴圈播放',
loopClose: '已關閉迴圈播放',
close: '關閉',
down: '下載',
p50: '50%',
p75: '75%',
p100: '100%',
timeScheduleAdjust: {
prohibit: '視頻禁止拖動',
prohibitBackOff: '視頻禁止重複觀看',
prohibitForward: '視頻禁止快進',
prohibitLookBack: '視頻禁止播放部分內容',
prohibitForwardNotViewed: '視頻禁止播放未觀看的部分'
},
error: {
noMessage: '未知錯誤',
supportVideoError: '該流覽器版本太低,建議更換成其它瀏覽器',
videoTypeError: '該瀏覽器不支持播放該視頻,建議更換成其它瀏覽器',
loadingFailed: '加載失敗',
emptied: '視頻檔案加載過程中出現錯誤',
screenshot: '視頻截圖失敗',
ajax: 'Ajax數據請求錯誤',
noVideoContainer: '未找到放置視頻的容器'
}
};
return language;
}))

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

BIN
public/video/first.mp4 Normal file

Binary file not shown.

View File

@ -73,13 +73,13 @@ export const getCoursesExample = async () => {
const response = await CourseApi.getCourses({
page: 1,
pageSize: 20,
category: '前端开发',
level: 'intermediate',
sortBy: 'rating'
categoryId: 1,
difficulty: 1,
sortBy: 'createdAt'
})
if (response.code === 200) {
const { list, total, page, pageSize } = response.data
const { list, total } = response.data
console.log('课程列表:', list)
console.log('总数:', total)
return response.data
@ -98,7 +98,7 @@ export const searchCoursesExample = async () => {
level: 'intermediate',
price: 'paid',
rating: 4,
sortBy: 'rating',
sortBy: 'newest',
page: 1,
pageSize: 10
})

191
src/api/mock/courses.ts Normal file
View File

@ -0,0 +1,191 @@
// 课程相关的Mock数据
// import type { CourseSection } from '../types'
// Course 和 CourseSection 类型暂时注释,后续需要时再启用
// Mock课程列表数据
export const mockCourses = [
{
id: 1,
name: "暑期名师领学,提高班级教学质量!高效冲分指南",
cover: "https://images.unsplash.com/photo-1516321318423-f06f85e504b3?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
categoryId: 1,
price: "99.00",
school: "名师工作室",
description: "本课程深度聚焦问题让每一位教师了解并学习使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为引导强调课程内容的易用性和岗位要求的匹配性。",
teacherId: 1,
outline: "课程大纲详细内容...",
prerequisite: "具备基本的计算机操作能力",
target: "掌握核心技能,能够在实际工作中熟练应用",
arrangement: "理论与实践相结合,循序渐进的学习方式",
startTime: "2025-01-26 10:13:17",
endTime: "2025-03-26 10:13:17",
revision: 1,
position: "高级讲师",
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null,
difficulty: 1
},
{
id: 2,
name: "Python编程基础与实战",
cover: "https://images.unsplash.com/photo-1526379095098-d400fd0bf935?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
categoryId: 2,
price: "199.00",
school: "编程技术学院",
description: "从零开始学习Python编程涵盖基础语法、数据结构、面向对象编程等核心概念通过实际项目练习掌握Python开发技能。",
teacherId: 2,
outline: "Python基础语法、数据类型、控制结构、函数、面向对象、文件操作、异常处理、模块和包、项目实战",
prerequisite: "无需编程基础,适合零基础学员",
target: "掌握Python编程基础能够独立完成简单的Python项目",
arrangement: "理论讲解 + 代码演示 + 实战练习",
startTime: "2025-01-20 09:00:00",
endTime: "2025-04-20 18:00:00",
revision: 1,
position: "Python开发专家",
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null,
difficulty: 1
},
{
id: 3,
name: "Vue.js 3 完整开发教程",
cover: "https://images.unsplash.com/photo-1555066931-4365d14bab8c?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
categoryId: 1,
price: "299.00",
school: "前端技术学院",
description: "深入学习Vue.js 3框架包括Composition API、TypeScript集成、状态管理、路由配置等现代前端开发技术。",
teacherId: 3,
outline: "Vue.js基础、组件开发、Composition API、状态管理、路由、项目构建、性能优化",
prerequisite: "具备HTML、CSS、JavaScript基础",
target: "掌握Vue.js 3开发技能能够独立开发前端项目",
arrangement: "视频教学 + 代码实战 + 项目练习",
startTime: "2025-02-01 10:00:00",
endTime: "2025-05-01 20:00:00",
revision: 1,
position: "前端架构师",
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null,
difficulty: 2
},
{
id: 4,
name: "React 18 实战开发",
cover: "https://images.unsplash.com/photo-1633356122544-f134324a6cee?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
categoryId: 1,
price: "399.00",
school: "前端技术学院",
description: "掌握React 18的新特性包括并发渲染、Suspense、Hooks等高级功能通过实际项目提升React开发技能。",
teacherId: 4,
outline: "React基础、组件设计、Hooks、状态管理、路由、测试、部署",
prerequisite: "具备JavaScript ES6+基础,了解前端开发流程",
target: "精通React开发能够构建复杂的单页应用",
arrangement: "理论 + 实践 + 项目驱动",
startTime: "2025-02-15 14:00:00",
endTime: "2025-06-15 22:00:00",
revision: 1,
position: "React技术专家",
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null,
difficulty: 3
},
{
id: 5,
name: "Node.js 后端开发实战",
cover: "https://images.unsplash.com/photo-1627398242454-45a1465c2479?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
categoryId: 3,
price: "349.00",
school: "后端技术学院",
description: "学习Node.js后端开发包括Express框架、数据库操作、API设计、身份验证、部署等全栈开发技能。",
teacherId: 5,
outline: "Node.js基础、Express框架、数据库、API设计、身份验证、测试、部署",
prerequisite: "具备JavaScript基础了解HTTP协议",
target: "掌握Node.js后端开发能够构建完整的后端服务",
arrangement: "理论讲解 + 实战项目 + 部署实践",
startTime: "2025-03-01 09:00:00",
endTime: "2025-07-01 18:00:00",
revision: 1,
position: "全栈开发工程师",
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null,
difficulty: 2
}
]
// Mock课程详情数据
export const getMockCourseDetail = (id: number) => {
const course = mockCourses.find(c => c.id === id)
if (!course) return null
return course
}
// Mock课程章节数据
export const getMockCourseSections = (lessonId: number) => {
return [
{
id: 1,
name: "第一章:课程介绍",
outline: "本章节介绍课程的基本概念和学习目标,帮助学员了解课程结构和学习方法。包含课程概述、学习目标、课程安排等内容。",
lessonId: lessonId,
sortOrder: 1,
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null
},
{
id: 2,
name: "第二章:基础理论",
outline: "深入学习相关的基础理论知识,为后续的实践学习打下坚实的理论基础。涵盖核心概念、基本原理、理论框架等。",
lessonId: lessonId,
sortOrder: 2,
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null
},
{
id: 3,
name: "第三章:实践应用",
outline: "通过实际案例和动手练习,将理论知识应用到实践中。包含案例分析、实操演示、练习题目等。",
lessonId: lessonId,
sortOrder: 3,
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null
},
{
id: 4,
name: "第四章:高级技巧",
outline: "学习高级技巧和最佳实践,提升专业技能水平。涵盖进阶方法、优化技巧、专业工具使用等。",
lessonId: lessonId,
sortOrder: 4,
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null
},
{
id: 5,
name: "第五章:项目实战",
outline: "通过完整的项目实战,综合运用所学知识。包含项目规划、实施过程、成果展示等环节。",
lessonId: lessonId,
sortOrder: 5,
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null
},
{
id: 6,
name: "第六章:考试测验",
outline: "通过在线考试检验学习成果,包含单选题、多选题、判断题、填空题和简答题等多种题型。",
lessonId: lessonId,
sortOrder: 6,
createdAt: 1737944724,
updatedAt: 1737944724,
updatedTime: null
}
]
}

228
src/api/modules/activity.ts Normal file
View File

@ -0,0 +1,228 @@
// import request from '../request'
import type { ApiResponse } from '../types'
// 活动相关的类型定义
export interface Activity {
id: number
title: string
subtitle: string
description: string
startDate: string
endDate: string
status: 'upcoming' | 'ongoing' | 'ended'
registrationCount: number
likeCount: number
categories: string[]
timeline: ActivityTimelineItem[]
content: ActivityContentItem[]
images: string[]
organizer: string
coOrganizer?: string
}
export interface ActivityTimelineItem {
date: string
title: string
description: string
}
export interface ActivityContentItem {
text: string
downloadLink?: string
}
export interface ActivityListItem {
id: number
title: string
subtitle: string
courseTitle: string
schedule: string
duration: string
students: string
price: string
status: string
image: string
}
// 活动API类
export class ActivityApi {
// 获取活动列表
static async getActivities(): Promise<ApiResponse<ActivityListItem[]>> {
try {
// 模拟API调用 - 实际项目中这里应该调用真实的API
const mockData: ActivityListItem[] = [
{
id: 1,
title: '计算机二级',
subtitle: 'C语言讲练综合班',
courseTitle: '计算机二级C语言程序设计证书',
schedule: '开课时间2025.07.26-2025.09.28',
duration: '适合年级:高校本科生',
students: '已报名1468/2000',
price: '免费',
status: '进行中',
image: '/images/activity/活动图1.png'
},
{
id: 2,
title: 'AI创新实践',
subtitle: '全国青少年人工智能创新实践活动',
courseTitle: '与AI共创未来 - 2025年全国青少年人工智能创新实践活动',
schedule: '开课时间2025.01.26-2025.09.22',
duration: '适合年级:中小学生',
students: '已报名541/1000',
price: '免费',
status: '报名中',
image: '/images/activity/活动图2.png'
}
]
return {
code: 0,
message: '获取活动列表成功',
data: mockData
}
} catch (error) {
console.error('获取活动列表失败:', error)
return {
code: -1,
message: '获取活动列表失败',
data: []
}
}
}
// 根据ID获取活动详情
static async getActivityById(id: number): Promise<ApiResponse<Activity>> {
try {
// 模拟API调用 - 实际项目中这里应该调用真实的API
const mockActivity: Activity = {
id: id,
title: '"与AI共创未来"',
subtitle: '2025年全国青少年人工智能创新实践活动',
description: '本活动是面向全国以青少年为主体的人工智能DeepSeek该活动以公司自主研发的创新成果以实践工作作为引导向青少年群体宣传推广人工智能技术让青少年了解人工智能技术的发展历程体验人工智能技术带来的便利培养青少年对人工智能技术的兴趣提升青少年的科学素养为我国人工智能技术的发展培养后备人才。在此基础上通过实践活动的开展让青少年在实践中学习在学习中实践。',
startDate: '2025-01-26',
endDate: '2025-09-22',
status: 'ongoing',
registrationCount: 541,
likeCount: 2377,
categories: [
'AI少年明日程',
'AI实习程序员',
'AI工程实践营',
'AI智能未来营',
'AI编程教学创新实验'
],
timeline: [
{
date: '7月1日-7月24日',
title: '青少年编程技能实践活动报名参赛',
description: ''
},
{
date: '7月25日-8月31日',
title: '青少年编程技能竞赛活动、开发实践活动',
description: ''
},
{
date: '8月31日-9月5日',
title: '实践作品提交和技能竞赛活动开展',
description: ''
},
{
date: '9月6日-9月20日',
title: '优秀作品公示期',
description: ''
},
{
date: '9月21日-9月27日',
title: '人工智能实践活动总结活动举办',
description: ''
}
],
content: [
{
text: '中国科协青少年科技中心、中国青少年科技教育工作者协会等',
downloadLink: undefined
},
{
text: '作品提交规则说明',
downloadLink: '#'
},
{
text: '中小学教师人工智能素养提升在线学习平台(网址)',
downloadLink: '#'
},
{
text: '作品提交 报名表',
downloadLink: '#'
}
],
images: [
'/images/activity/活动图1.png',
'/images/activity/活动图2.png',
'/images/activity/活动图3.png'
],
organizer: '中国科协青少年科技中心',
coOrganizer: '中国青少年科技教育工作者协会、上海人工智能实验室'
}
return {
code: 0,
message: '获取活动详情成功',
data: mockActivity
}
} catch (error) {
console.error('获取活动详情失败:', error)
return {
code: -1,
message: '获取活动详情失败',
data: {} as Activity
}
}
}
// 报名活动
static async registerActivity(activityId: number): Promise<ApiResponse<any>> {
try {
// 模拟API调用
console.log('报名活动:', activityId)
return {
code: 0,
message: '报名成功',
data: { success: true }
}
} catch (error) {
console.error('报名活动失败:', error)
return {
code: -1,
message: '报名失败',
data: { success: false }
}
}
}
// 提交作品
static async submitWork(activityId: number, workData: any): Promise<ApiResponse<any>> {
try {
// 模拟API调用
console.log('提交作品:', activityId, workData)
return {
code: 0,
message: '作品提交成功',
data: { success: true }
}
} catch (error) {
console.error('提交作品失败:', error)
return {
code: -1,
message: '作品提交失败',
data: { success: false }
}
}
}
}
export default ActivityApi

View File

@ -5,7 +5,7 @@ import type {
User,
LoginRequest,
LoginResponse,
BackendLoginResponse,
// BackendLoginResponse,
RegisterRequest,
UserProfile,
} from '../types'
@ -17,33 +17,167 @@ export class AuthApi {
// 用户登录
static async login(data: LoginRequest): Promise<ApiResponse<LoginResponse>> {
try {
// 调用后端API
const response = await ApiRequest.post<BackendLoginResponse>('/users/login', data)
console.log('🚀 发送登录请求:', { url: '/users/login', data: { ...data, password: '***' } })
// 适配后端响应格式为前端期望的格式
const adaptedResponse: ApiResponse<LoginResponse> = {
code: response.code,
message: response.message,
data: {
user: {
id: response.data.id, // 使用后端返回的用户ID
email: data.email || '',
phone: data.phone || '',
username: data.phone || data.email?.split('@')[0] || 'user',
nickname: '用户',
avatar: '',
role: 'student',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
},
token: response.data.token,
refreshToken: '', // 后端没有返回,使用空字符串
expiresIn: 3600 // 默认1小时可以根据expires字段计算
// 调用后端API
const response = await ApiRequest.post<any>('/users/login', data)
console.log('🔍 Login API Response:', response)
console.log('🔍 Response Code:', response.code)
console.log('🔍 Response Data:', response.data)
console.log('🔍 Response Data Type:', typeof response.data)
// 处理响应格式问题 - 如果code和message是undefined可能是响应拦截器的问题
let actualCode = response.code
let actualMessage = response.message
let actualData = response.data
// 如果response.code是undefined检查response.data是否包含完整的API响应
if (actualCode === undefined && actualData && typeof actualData === 'object') {
if ('code' in actualData && 'message' in actualData && 'data' in actualData) {
// 这种情况下真正的API响应被包装在了response.data中
actualCode = actualData.code
actualMessage = actualData.message
actualData = actualData.data
console.log('🔧 修正后的响应:', { code: actualCode, message: actualMessage, data: actualData })
}
}
return adaptedResponse
// 检查响应格式并适配
if (actualCode === 200 || actualCode === 0) {
// 如果后端返回的是完整的用户信息格式mock数据格式
if (actualData && actualData.user && actualData.token) {
return {
code: actualCode,
message: actualMessage,
data: actualData
} as ApiResponse<LoginResponse>
}
// 如果后端返回的是真实API格式包含token, timestamp, expires
if (actualData && actualData.token && actualData.timestamp) {
const adaptedResponse: ApiResponse<LoginResponse> = {
code: actualCode,
message: actualMessage || '登录成功',
data: {
user: {
id: 1, // 真实API没有返回用户ID使用默认值
email: data.email || '',
phone: data.phone || '',
username: data.phone || data.email?.split('@')[0] || 'user',
nickname: '用户',
avatar: '',
role: 'student',
status: 'active',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
},
token: actualData.token,
refreshToken: '', // 真实API没有返回refreshToken
expiresIn: 3600 // 默认1小时过期
}
}
return adaptedResponse
}
// 如果后端返回的是简化格式BackendLoginResponse
if (actualData && actualData.token) {
const adaptedResponse: ApiResponse<LoginResponse> = {
code: actualCode,
message: actualMessage || '登录成功',
data: {
user: {
id: actualData.id || 1,
email: data.email || '',
phone: data.phone || '',
username: data.phone || data.email?.split('@')[0] || 'user',
nickname: '用户',
avatar: '',
role: 'student',
status: 'active',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
},
token: actualData.token,
refreshToken: actualData.refreshToken || '',
expiresIn: actualData.expiresIn || 3600
}
}
return adaptedResponse
}
// 如果只有token字段直接使用token
if (typeof actualData === 'string') {
const adaptedResponse: ApiResponse<LoginResponse> = {
code: actualCode,
message: actualMessage || '登录成功',
data: {
user: {
id: 1,
email: data.email || '',
phone: data.phone || '',
username: data.phone || data.email?.split('@')[0] || 'user',
nickname: '用户',
avatar: '',
role: 'student',
status: 'active',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
},
token: actualData,
refreshToken: '',
expiresIn: 3600
}
}
return adaptedResponse
}
// 如果data是null或undefined但响应成功可能是某些API的特殊情况
if (!actualData) {
console.warn('⚠️ API返回成功但data为空可能需要检查API实现')
throw new Error('登录成功但未返回用户信息')
}
// 尝试处理其他可能的响应格式
console.warn('⚠️ 未知的响应格式,尝试通用处理:', actualData)
// 如果data是对象但不包含预期字段尝试创建默认响应
if (typeof actualData === 'object') {
const adaptedResponse: ApiResponse<LoginResponse> = {
code: actualCode,
message: actualMessage || '登录成功',
data: {
user: {
id: actualData.id || actualData.userId || 1,
email: data.email || '',
phone: data.phone || '',
username: data.phone || data.email?.split('@')[0] || 'user',
nickname: actualData.nickname || actualData.name || '用户',
avatar: actualData.avatar || '',
role: actualData.role || 'student',
status: 'active',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
},
token: actualData.accessToken || actualData.access_token || 'temp_token_' + Date.now(),
refreshToken: actualData.refreshToken || actualData.refresh_token || '',
expiresIn: actualData.expiresIn || actualData.expires_in || 3600
}
}
return adaptedResponse
}
}
// 如果响应格式不符合预期,抛出错误
console.error('🚨 Unexpected response format:', {
code: actualCode,
message: actualMessage,
data: actualData,
dataType: typeof actualData
})
throw new Error(actualMessage || '登录响应格式错误')
} catch (error) {
console.error('🚨 Login API Error:', error)
throw error
}
}
@ -55,7 +189,24 @@ export class AuthApi {
// 用户登出
static logout(): Promise<ApiResponse<null>> {
return ApiRequest.post('/auth/logout')
// 尝试多个可能的登出端点
return ApiRequest.post('/auth/logout').catch(async (error) => {
// 如果 /auth/logout 失败,尝试其他可能的端点
if (error.response?.status === 404) {
try {
return await ApiRequest.post('/users/logout')
} catch (secondError) {
// 如果所有端点都失败,返回成功(客户端登出)
console.log('所有登出端点都不存在,执行客户端登出')
return {
code: 200,
message: '登出成功',
data: null
}
}
}
throw error
})
}
// 刷新Token

Some files were not shown because too many files have changed in this diff Show More