这是我参与「第五届青训营 」笔记创作活动的第7天
今日成果
ssh服务器
搭建: www.bilibili.com/video/BV1rz…
ffmpeg : sudo snap install ffmpeg
wpy云服务器上:sudo apt-get install ffmpeg
ssh和ffmpeg 配置好之后检查是否成功
搭建环境是否成功测试 :
1.修改config.go文件下变量Ssh_addr_port、Ssh_username、Ssh_password为自己服务器对应的参数
2.创建config.go文件下变量Ftp_video_path、Ftp_image_path对应的路径(可自己定义)
3.将data目录下的bear.mp4文件存放在config.go文件的Ftp_video_path变量记录的路径下
4.cd到ffmpeg文件夹下
go test5.Ftp_image_path路径下出现bear.jpg和bear2.jpg文件 则配置成功
openssl采用口令方式登陆,服务器提供公钥给客户端,客户端用公钥加密自己的密码后发回,服务器用私钥解密验证
openssl默认60s断开连接,因此需要加入应用层客户端心跳。
当前实现客户端方未验证服务器公钥是否正确,若实际生产环境需得到服务器公钥到配置文件中,防止中间人截获并伪装服务器
type Ffmsg struct {
VideoName string
ImageName string
}
var ClientSSH *ssh.Client
var Ffchan chan Ffmsg
func Init() {
var err error
clientConfig := &ssh.ClientConfig{
Timeout: time.Second * 5, //最多5s建立连接
User: config.Ssh_username,
Auth: []ssh.AuthMethod{
ssh.Password(config.Ssh_password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(), //不检查公钥
}
ClientSSH, err = ssh.Dial("tcp", config.Ssh_addr_port, clientConfig)
if err != nil {
log.Fatal("Failed to dial: ", err)
}
Ffchan = make(chan Ffmsg, config.Ssh_max_taskCnt)
go dispatcher()
go keepalive()
log.Println("ssh初始化成功")
}
// 将ffmpeg命令以及其参数通过ssh运行,若运行失败,则重新放入channel运行
func dispatcher() {
for ffmsg := range Ffchan {
go func(f Ffmsg) {
err := Ffmpeg(f.VideoName, f.ImageName)
if err != nil {
Ffchan <- f
log.Println("ffmpeg调用失败,等待重新执行")
}
}(ffmsg)
}
}
func Ffmpeg(videoName, imageName string) error {
// Each ClientConn can support multiple interactive sessions,
// represented by a Session.
session, err := ClientSSH.NewSession()
if err != nil {
log.Fatal("Failed to create session: ", err)
}
defer session.Close()
// Once a Session is created, you can execute a single command on
// the remote side using the Run method.
var b bytes.Buffer
session.Stdout = &b
if err := session.Run("ffmpeg -ss 00:00:01 -i " + config.Ftp_video_path + videoName + ".mp4 -vframes 1 " + config.Ftp_image_path + imageName + ".jpg"); err != nil {
log.Println("SSH failed to run: " + err.Error())
log.Println("远端输出错误信息 : ", b.String())
return err
}
log.Println("ffmpeg 执行成功")
return nil
}
// openssl 默认为60s断开连接, 因此设置10s一次心跳
func keepalive() {
for {
s, err := ClientSSH.NewSession()
if err != nil {
log.Println("ssh连接断开! err : ", err)
}
time.Sleep(10 * time.Second)
s.Close()
}
}