EduSoho 是一款功能强大的网校系统,能够帮助教育机构快速搭建在线学习平台。本文将详细介绍如何在华为云服务器上安装和部署 EduSoho 网校系统,以及二次开发对接华为云视频点播VOD来实现CDN加速播放。
edusoho本地存储的视频播放存在诸多弊端。一方面,本地存储受限于服务器的性能和带宽,当大量用户同时访问时,很容易出现加载慢的情况。尤其是在高峰时段,视频的加载可能会变得极为缓慢,甚至出现卡顿、无法播放的现象,极大地影响了用户的观看体验。另一方面,本地存储需要视频网站投入大量的资金和精力进行服务器的维护和升级,成本较高。而且,一旦服务器出现故障,可能会导致视频数据的丢失,给视频网站带来不可挽回的损失。
相比之下,edusoho二次开发对接华为云视频点播 VOD 则具有明显的优势。
-
其一,华为云视频点播 VOD
拥有强大的云计算能力和高速的网络带宽,可以实现视频的快速加载和流畅播放。无论何时何地,用户都能享受到高质量的视频观看体验,无需担心加载慢的问题。
-
其二,华为云视频点播 VOD
提供了丰富的视频处理功能,如转码、加密、截图等,可以满足视频网站的各种需求。同时,它还支持多种视频格式和分辨率,适应不同设备和网络环境的播放要求。
-
其三,华为云视频点播 VOD
具有高可靠性和安全性。它采用了先进的分布式存储技术和数据备份机制,确保视频数据的安全可靠。即使出现硬件故障或自然灾害等情况,也能保证视频的正常播放。
一、开始环境准备
- 选择并购买华为云服务器Flexus X
1.2 进入华为云官网(https://www.huaweicloud.com/product/flexus-x.html),登录或注册账号并完成实名认证。在产品页面选择"华为云Flexus云服务器X",根据需求选择合适的服务器配置(如CPU、内存、存储等),并选择合适的操作系统,推荐选择Ubuntu,因为 EduSoho 在该操作系统上兼容性较好。完成选择和配置后,点击"立即购买"并完成支付。
1.3 重置密码并配置安全组
购买完成后,在华为云控制台中找到你的服务器实例,点击"重置密码"并记住新密码。然后,进入"安全组"配置,在入方向规则中添加必要的端口,如 HTTP(80)和 HTTPS(443)端口,以及 SSH(22)端口用于远程管理。
二、ssh远程连接服务器
下载并安装 putty.exe 客户端,用于远程连接你的华为云服务器。在 putty.exe 中新建会话,输入服务器的 IP 地址、用户名(默认为 root)和密码,点击连接。
三、安装必要的软件
3.1 初始化环境
在服务器上执行以下命令来安装 wget 并关闭防火墙及 SELinux:
bash
bash
yum install -y wget
systemctl stop firewalld.service
systemctl disable firewalld.service
setenforce 0
3.2 或者永久关闭 SELinux
bash
sudo vi /etc/selinux/config
bash
将 SELINUX=enforcing 改为 SELINUX=disabled
3.3 安装 Nginx PHP7.3 MySQL5.7 phpMyAdmin5.1等一些列服务器必备的环境组件
3.4 在 http{} 配置中加入:
bash
client_max_body_size 2048M;
3.5 启动 Nginx
bash
systemctl start nginx.service
3.6 设置 Nginx 为开机启动
bash
systemctl enable nginx.service
3.7 修改以下配置的值:
bash
post_max_size = 1024M
memory_limit = 1024M
upload_max_filesize = 1024M
启动 PHP-FPM
systemctl start php-fpm.service
3.8 重启 Nginx
bash
systemctl restart nginx.service
四、把edusoho程序压缩包上传到你建立的网站更目录下
4.1 把 .ZIP 压缩包进行解压
五、 配置网站的伪静态
python
location / {
index app.php;
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
六、 在浏览器中输入 http://您的域名/ 就可以进入安装界面了,按照安装向导完成剩余的安装步骤
七、检测网站目录是否开启对应的写入权限
八、填写数据库账号密码、端口号等等
九、 进入到安装向导的第三步,填写好您的网站信息
十、搭建好之后就可以进入网校系统的web界面
十一、华为云点播VOD
华为云点播是集视频上传、自动化转码处理、媒体资源管理、分发加速、视频播放于一体的一站式媒体服务。借助华为云提供灵活弹性解决方案,您无需关注服务依赖的底层基础设施,只需要依托高质量的媒体处理服务来快速搭建安全、弹性的点播平台。
选购华为云点播CDN流量包
十二、在后台配置个人的华为云视频账号信息 HUAWEICLOUD_SDK_AK和 HUAWEICLOUD_SDK_SK
VideoInfo.php的代码展示
php
<?php
namespace HuaweiCloud\SDK\Vod\V1\Model;
use \ArrayAccess;
use HuaweiCloud\SDK\Core\Utils\ObjectSerializer;
use HuaweiCloud\SDK\Core\Utils\ModelInterface;
use HuaweiCloud\SDK\Core\SdkResponse;
class VideoInfo implements ModelInterface, ArrayAccess
{
const DISCRIMINATOR = null;
/**
* The original name of the model.
*
* @var string
*/
protected static $openAPIModelName = 'VideoInfo';
/**
* Array of property to type mappings. Used for (de)serialization
* quality 画质<br/> 4K默认分辨率3840*2160,码率8000kbit/s<br/> 2K默认分辨率2560*1440,码率7000kbit/s<br/> FULL_HD默认分辨率1920*1080,码率3000kbit/s<br/> HD默认分辨率1280*720,码率1000kbit/s<br/> SD默认分辨率854*480,码率600kbit/s<br/> FLUENT默认分辨率480*270,码率300kbit/s<br/>
* width 视频宽度<br/>
* height 视频高度<br/>
* bitrate 码率,单位:kbit/s<br/>
* frameRate 帧率(默认为0,0代表自适应,单位是帧每秒)<br/>
*
* @var string[]
*/
protected static $openAPITypes = [
'quality' => 'string',
'width' => 'int',
'height' => 'int',
'bitrate' => 'int',
'frameRate' => 'int'
];
/**
* Array of property to format mappings. Used for (de)serialization
* quality 画质<br/> 4K默认分辨率3840*2160,码率8000kbit/s<br/> 2K默认分辨率2560*1440,码率7000kbit/s<br/> FULL_HD默认分辨率1920*1080,码率3000kbit/s<br/> HD默认分辨率1280*720,码率1000kbit/s<br/> SD默认分辨率854*480,码率600kbit/s<br/> FLUENT默认分辨率480*270,码率300kbit/s<br/>
* width 视频宽度<br/>
* height 视频高度<br/>
* bitrate 码率,单位:kbit/s<br/>
* frameRate 帧率(默认为0,0代表自适应,单位是帧每秒)<br/>
*
* @var string[]
*/
protected static $openAPIFormats = [
'quality' => null,
'width' => null,
'height' => null,
'bitrate' => null,
'frameRate' => null
];
/**
* Array of property to type mappings. Used for (de)serialization
*
* @return array
*/
public static function openAPITypes()
{
return self::$openAPITypes;
}
/**
* Array of property to format mappings. Used for (de)serialization
*
* @return array
*/
public static function openAPIFormats()
{
return self::$openAPIFormats;
}
/**
* Array of attributes where the key is the local name,
* and the value is the original name
* quality 画质<br/> 4K默认分辨率3840*2160,码率8000kbit/s<br/> 2K默认分辨率2560*1440,码率7000kbit/s<br/> FULL_HD默认分辨率1920*1080,码率3000kbit/s<br/> HD默认分辨率1280*720,码率1000kbit/s<br/> SD默认分辨率854*480,码率600kbit/s<br/> FLUENT默认分辨率480*270,码率300kbit/s<br/>
* width 视频宽度<br/>
* height 视频高度<br/>
* bitrate 码率,单位:kbit/s<br/>
* frameRate 帧率(默认为0,0代表自适应,单位是帧每秒)<br/>
*
* @var string[]
*/
protected static $attributeMap = [
'quality' => 'quality',
'width' => 'width',
'height' => 'height',
'bitrate' => 'bitrate',
'frameRate' => 'frame_rate'
];
/**
* Array of attributes to setter functions (for deserialization of responses)
* quality 画质<br/> 4K默认分辨率3840*2160,码率8000kbit/s<br/> 2K默认分辨率2560*1440,码率7000kbit/s<br/> FULL_HD默认分辨率1920*1080,码率3000kbit/s<br/> HD默认分辨率1280*720,码率1000kbit/s<br/> SD默认分辨率854*480,码率600kbit/s<br/> FLUENT默认分辨率480*270,码率300kbit/s<br/>
* width 视频宽度<br/>
* height 视频高度<br/>
* bitrate 码率,单位:kbit/s<br/>
* frameRate 帧率(默认为0,0代表自适应,单位是帧每秒)<br/>
*
* @var string[]
*/
protected static $setters = [
'quality' => 'setQuality',
'width' => 'setWidth',
'height' => 'setHeight',
'bitrate' => 'setBitrate',
'frameRate' => 'setFrameRate'
];
/**
* Array of attributes to getter functions (for serialization of requests)
* quality 画质<br/> 4K默认分辨率3840*2160,码率8000kbit/s<br/> 2K默认分辨率2560*1440,码率7000kbit/s<br/> FULL_HD默认分辨率1920*1080,码率3000kbit/s<br/> HD默认分辨率1280*720,码率1000kbit/s<br/> SD默认分辨率854*480,码率600kbit/s<br/> FLUENT默认分辨率480*270,码率300kbit/s<br/>
* width 视频宽度<br/>
* height 视频高度<br/>
* bitrate 码率,单位:kbit/s<br/>
* frameRate 帧率(默认为0,0代表自适应,单位是帧每秒)<br/>
*
* @var string[]
*/
protected static $getters = [
'quality' => 'getQuality',
'width' => 'getWidth',
'height' => 'getHeight',
'bitrate' => 'getBitrate',
'frameRate' => 'getFrameRate'
];
/**
* Array of attributes where the key is the local name,
* and the value is the original name
*
* @return array
*/
public static function attributeMap()
{
return self::$attributeMap;
}
/**
* Array of attributes to setter functions (for deserialization of responses)
*
* @return array
*/
public static function setters()
{
return self::$setters;
}
/**
* Array of attributes to getter functions (for serialization of requests)
*
* @return array
*/
public static function getters()
{
return self::$getters;
}
/**
* The original name of the model.
*
* @return string
*/
public function getModelName()
{
return self::$openAPIModelName;
}
const QUALITY_FULL_HD = 'FULL_HD';
const QUALITY_HD = 'HD';
const QUALITY_SD = 'SD';
const QUALITY_FLUENT = 'FLUENT';
const QUALITY__2_K = '2K';
const QUALITY__4_K = '4K';
const QUALITY_UNKNOW = 'UNKNOW';
/**
* Gets allowable values of the enum
*
* @return string[]
*/
public function getQualityAllowableValues()
{
return [
self::QUALITY_FULL_HD,
self::QUALITY_HD,
self::QUALITY_SD,
self::QUALITY_FLUENT,
self::QUALITY__2_K,
self::QUALITY__4_K,
self::QUALITY_UNKNOW,
];
}
/**
* Associative array for storing property values
*
* @var mixed[]
*/
protected $container = [];
/**
* Constructor
*
* @param mixed[] $data Associated array of property values
* initializing the model
*/
public function __construct(array $data = null)
{
$this->container['quality'] = isset($data['quality']) ? $data['quality'] : null;
$this->container['width'] = isset($data['width']) ? $data['width'] : null;
$this->container['height'] = isset($data['height']) ? $data['height'] : null;
$this->container['bitrate'] = isset($data['bitrate']) ? $data['bitrate'] : null;
$this->container['frameRate'] = isset($data['frameRate']) ? $data['frameRate'] : null;
}
/**
* Show all the invalid properties with reasons.
*
* @return array invalid properties with reasons
*/
public function listInvalidProperties()
{
$invalidProperties = [];
if ($this->container['quality'] === null) {
$invalidProperties[] = "'quality' can't be null";
}
$allowedValues = $this->getQualityAllowableValues();
if (!is_null($this->container['quality']) && !in_array($this->container['quality'], $allowedValues, true)) {
$invalidProperties[] = sprintf(
"invalid value for 'quality', must be one of '%s'",
implode("', '", $allowedValues)
);
}
if ($this->container['bitrate'] === null) {
$invalidProperties[] = "'bitrate' can't be null";
}
if ($this->container['frameRate'] === null) {
$invalidProperties[] = "'frameRate' can't be null";
}
if (($this->container['frameRate'] > 60)) {
$invalidProperties[] = "invalid value for 'frameRate', must be smaller than or equal to 60.";
}
if (($this->container['frameRate'] < 0)) {
$invalidProperties[] = "invalid value for 'frameRate', must be bigger than or equal to 0.";
}
return $invalidProperties;
}
/**
* Validate all the properties in the model
* return true if all passed
*
* @return bool True if all properties are valid
*/
public function valid()
{
return count($this->listInvalidProperties()) === 0;
}
/**
* Gets quality
* 画质<br/> 4K默认分辨率3840*2160,码率8000kbit/s<br/> 2K默认分辨率2560*1440,码率7000kbit/s<br/> FULL_HD默认分辨率1920*1080,码率3000kbit/s<br/> HD默认分辨率1280*720,码率1000kbit/s<br/> SD默认分辨率854*480,码率600kbit/s<br/> FLUENT默认分辨率480*270,码率300kbit/s<br/>
*
* @return string
*/
public function getQuality()
{
return $this->container['quality'];
}
/**
* Sets quality
*
* @param string $quality 画质<br/> 4K默认分辨率3840*2160,码率8000kbit/s<br/> 2K默认分辨率2560*1440,码率7000kbit/s<br/> FULL_HD默认分辨率1920*1080,码率3000kbit/s<br/> HD默认分辨率1280*720,码率1000kbit/s<br/> SD默认分辨率854*480,码率600kbit/s<br/> FLUENT默认分辨率480*270,码率300kbit/s<br/>
*
* @return $this
*/
public function setQuality($quality)
{
$this->container['quality'] = $quality;
return $this;
}
/**
* Gets width
* 视频宽度<br/>
*
* @return int|null
*/
public function getWidth()
{
return $this->container['width'];
}
/**
* Sets width
*
* @param int|null $width 视频宽度<br/>
*
* @return $this
*/
public function setWidth($width)
{
$this->container['width'] = $width;
return $this;
}
/**
* Gets height
* 视频高度<br/>
*
* @return int|null
*/
public function getHeight()
{
return $this->container['height'];
}
/**
* Sets height
*
* @param int|null $height 视频高度<br/>
*
* @return $this
*/
public function setHeight($height)
{
$this->container['height'] = $height;
return $this;
}
/**
* Gets bitrate
* 码率,单位:kbit/s<br/>
*
* @return int
*/
public function getBitrate()
{
return $this->container['bitrate'];
}
/**
* Sets bitrate
*
* @param int $bitrate 码率,单位:kbit/s<br/>
*
* @return $this
*/
public function setBitrate($bitrate)
{
$this->container['bitrate'] = $bitrate;
return $this;
}
/**
* Gets frameRate
* 帧率(默认为0,0代表自适应,单位是帧每秒)<br/>
*
* @return int
*/
public function getFrameRate()
{
return $this->container['frameRate'];
}
/**
* Sets frameRate
*
* @param int $frameRate 帧率(默认为0,0代表自适应,单位是帧每秒)<br/>
*
* @return $this
*/
public function setFrameRate($frameRate)
{
$this->container['frameRate'] = $frameRate;
return $this;
}
/**
* Returns true if offset exists. False otherwise.
*
* @param integer $offset Offset
*
* @return boolean
*/
public function offsetExists($offset)
{
return isset($this->container[$offset]);
}
/**
* Gets offset.
*
* @param integer $offset Offset
*
* @return mixed
*/
public function offsetGet($offset)
{
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
/**
* Sets value based on offset.
*
* @param integer $offset Offset
* @param mixed $value Value to be set
*
* @return void
*/
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
/**
* Unsets offset.
*
* @param integer $offset Offset
*
* @return void
*/
public function offsetUnset($offset)
{
unset($this->container[$offset]);
}
/**
* Gets the string presentation of the object
*
* @return string
*/
public function __toString()
{
return json_encode(
ObjectSerializer::sanitizeForSerialization($this),
JSON_PRETTY_PRINT
);
}
}
12.1 创建一个普通课程,进行测试一下效果
12.2 开始创建课程
12.3 添加课时
UploadAsset.php代码的展示
php
<?php
namespace HuaweiCloud\SDK\Vod\V1\Model;
use \ArrayAccess;
use HuaweiCloud\SDK\Core\Utils\ObjectSerializer;
use HuaweiCloud\SDK\Core\Utils\ModelInterface;
use HuaweiCloud\SDK\Core\SdkResponse;
class UploadAsset implements ModelInterface, ArrayAccess
{
const DISCRIMINATOR = null;
/**
* The original name of the model.
*
* @var string
*/
protected static $openAPIModelName = 'UploadAsset';
/**
* Array of property to type mappings. Used for (de)serialization
* url 媒资所在url
* assetId 新创建媒资的媒资id
* errorCode 错误码。
* errorMsg 错误描述。
*
* @var string[]
*/
protected static $openAPITypes = [
'url' => 'string',
'assetId' => 'string',
'errorCode' => 'string',
'errorMsg' => 'string'
];
/**
* Array of property to format mappings. Used for (de)serialization
* url 媒资所在url
* assetId 新创建媒资的媒资id
* errorCode 错误码。
* errorMsg 错误描述。
*
* @var string[]
*/
protected static $openAPIFormats = [
'url' => null,
'assetId' => null,
'errorCode' => null,
'errorMsg' => null
];
/**
* Array of property to type mappings. Used for (de)serialization
*
* @return array
*/
public static function openAPITypes()
{
return self::$openAPITypes;
}
/**
* Array of property to format mappings. Used for (de)serialization
*
* @return array
*/
public static function openAPIFormats()
{
return self::$openAPIFormats;
}
/**
* Array of attributes where the key is the local name,
* and the value is the original name
* url 媒资所在url
* assetId 新创建媒资的媒资id
* errorCode 错误码。
* errorMsg 错误描述。
*
* @var string[]
*/
protected static $attributeMap = [
'url' => 'url',
'assetId' => 'asset_id',
'errorCode' => 'error_code',
'errorMsg' => 'error_msg'
];
/**
* Array of attributes to setter functions (for deserialization of responses)
* url 媒资所在url
* assetId 新创建媒资的媒资id
* errorCode 错误码。
* errorMsg 错误描述。
*
* @var string[]
*/
protected static $setters = [
'url' => 'setUrl',
'assetId' => 'setAssetId',
'errorCode' => 'setErrorCode',
'errorMsg' => 'setErrorMsg'
];
/**
* Array of attributes to getter functions (for serialization of requests)
* url 媒资所在url
* assetId 新创建媒资的媒资id
* errorCode 错误码。
* errorMsg 错误描述。
*
* @var string[]
*/
protected static $getters = [
'url' => 'getUrl',
'assetId' => 'getAssetId',
'errorCode' => 'getErrorCode',
'errorMsg' => 'getErrorMsg'
];
/**
* Array of attributes where the key is the local name,
* and the value is the original name
*
* @return array
*/
public static function attributeMap()
{
return self::$attributeMap;
}
/**
* Array of attributes to setter functions (for deserialization of responses)
*
* @return array
*/
public static function setters()
{
return self::$setters;
}
/**
* Array of attributes to getter functions (for serialization of requests)
*
* @return array
*/
public static function getters()
{
return self::$getters;
}
/**
* The original name of the model.
*
* @return string
*/
public function getModelName()
{
return self::$openAPIModelName;
}
/**
* Associative array for storing property values
*
* @var mixed[]
*/
protected $container = [];
/**
* Constructor
*
* @param mixed[] $data Associated array of property values
* initializing the model
*/
public function __construct(array $data = null)
{
$this->container['url'] = isset($data['url']) ? $data['url'] : null;
$this->container['assetId'] = isset($data['assetId']) ? $data['assetId'] : null;
$this->container['errorCode'] = isset($data['errorCode']) ? $data['errorCode'] : null;
$this->container['errorMsg'] = isset($data['errorMsg']) ? $data['errorMsg'] : null;
}
/**
* Show all the invalid properties with reasons.
*
* @return array invalid properties with reasons
*/
public function listInvalidProperties()
{
$invalidProperties = [];
return $invalidProperties;
}
/**
* Validate all the properties in the model
* return true if all passed
*
* @return bool True if all properties are valid
*/
public function valid()
{
return count($this->listInvalidProperties()) === 0;
}
/**
* Gets url
* 媒资所在url
*
* @return string|null
*/
public function getUrl()
{
return $this->container['url'];
}
/**
* Sets url
*
* @param string|null $url 媒资所在url
*
* @return $this
*/
public function setUrl($url)
{
$this->container['url'] = $url;
return $this;
}
/**
* Gets assetId
* 新创建媒资的媒资id
*
* @return string|null
*/
public function getAssetId()
{
return $this->container['assetId'];
}
/**
* Sets assetId
*
* @param string|null $assetId 新创建媒资的媒资id
*
* @return $this
*/
public function setAssetId($assetId)
{
$this->container['assetId'] = $assetId;
return $this;
}
/**
* Gets errorCode
* 错误码。
*
* @return string|null
*/
public function getErrorCode()
{
return $this->container['errorCode'];
}
/**
* Sets errorCode
*
* @param string|null $errorCode 错误码。
*
* @return $this
*/
public function setErrorCode($errorCode)
{
$this->container['errorCode'] = $errorCode;
return $this;
}
/**
* Gets errorMsg
* 错误描述。
*
* @return string|null
*/
public function getErrorMsg()
{
return $this->container['errorMsg'];
}
/**
* Sets errorMsg
*
* @param string|null $errorMsg 错误描述。
*
* @return $this
*/
public function setErrorMsg($errorMsg)
{
$this->container['errorMsg'] = $errorMsg;
return $this;
}
/**
* Returns true if offset exists. False otherwise.
*
* @param integer $offset Offset
*
* @return boolean
*/
public function offsetExists($offset)
{
return isset($this->container[$offset]);
}
/**
* Gets offset.
*
* @param integer $offset Offset
*
* @return mixed
*/
public function offsetGet($offset)
{
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
/**
* Sets value based on offset.
*
* @param integer $offset Offset
* @param mixed $value Value to be set
*
* @return void
*/
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
/**
* Unsets offset.
*
* @param integer $offset Offset
*
* @return void
*/
public function offsetUnset($offset)
{
unset($this->container[$offset]);
}
/**
* Gets the string presentation of the object
*
* @return string
*/
public function __toString()
{
return json_encode(
ObjectSerializer::sanitizeForSerialization($this),
JSON_PRETTY_PRINT
);
}
}
十三、测试播放效果
13.1 在网站上点击播放一个视频, 可以看到视频已经实现华为云CDN加速播放了(播放加载速度)
13.2 手机端视频播放效果
十四、寄语:
系统维护与优化
- 定期备份数据
定期备份 MySQL 数据库和 EduSoho 的文件,以防数据丢失。
- 更新系统和软件
定期更新操作系统和所有已安装的软件,以修复安全漏洞和性能问题。
- 监控和优化性能
使用监控工具监控服务器的性能和资源使用情况,并根据需要进行优化。
- 安全性设置
加强服务器的安全性,包括设置防火墙、使用 SSL 证书、限制远程访问等。
通过以上步骤,你可以在华为云Flexus云服务器X实例上成功安装和部署 EduSoho 网校系统,并对其进行有效的维护和优化。
在性能方面,Flexus 云服务器 X 表现出色。它拥有强大的处理器和充足的内存,能够轻松应对各种复杂的业务场景。无论是高并发的在线教育、视频播放、电商直播,还是大规模的数据处理,它都能快速响应,确保业务的顺畅运行。