正在显示
13 个修改的文件
包含
299 行增加
和
1 行删除
1 | package v1 | 1 | package v1 |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "encoding/json" | ||
4 | "fmt" | 5 | "fmt" |
5 | "github.com/astaxie/beego" | 6 | "github.com/astaxie/beego" |
7 | + "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log" | ||
6 | "opp/controllers" | 8 | "opp/controllers" |
9 | + "opp/internal/aliyun" | ||
7 | "opp/internal/utils" | 10 | "opp/internal/utils" |
8 | "opp/protocol" | 11 | "opp/protocol" |
12 | + "opp/services/file" | ||
9 | "path/filepath" | 13 | "path/filepath" |
10 | "strings" | 14 | "strings" |
11 | ) | 15 | ) |
@@ -37,3 +41,24 @@ func (this *FileController) DownLoad() { | @@ -37,3 +41,24 @@ func (this *FileController) DownLoad() { | ||
37 | } | 41 | } |
38 | msg = protocol.NewReturnResponse(rsp, err) | 42 | msg = protocol.NewReturnResponse(rsp, err) |
39 | } | 43 | } |
44 | + | ||
45 | +//GetPlayInfo 获取播放信息 | ||
46 | +// @router /getPlayInfo [post] | ||
47 | +func (this *FileController) GetPlayInfo() { | ||
48 | + var msg *protocol.ResponseMessage | ||
49 | + defer func() { | ||
50 | + this.Resp(msg) | ||
51 | + }() | ||
52 | + var request *aliyun.GetPlayInfoRequest | ||
53 | + if err := json.Unmarshal(this.ByteBody, &request); err != nil { | ||
54 | + log.Error(err) | ||
55 | + msg = protocol.BadRequestParam(1) | ||
56 | + return | ||
57 | + } | ||
58 | + if b, m := this.Valid(request); !b { | ||
59 | + msg = m | ||
60 | + return | ||
61 | + } | ||
62 | + header := controllers.GetRequestHeader(this.Ctx) | ||
63 | + msg = protocol.NewReturnResponse(file.GetPlayInfo(header, request)) | ||
64 | +} |
@@ -2,8 +2,10 @@ package v1 | @@ -2,8 +2,10 @@ package v1 | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "bytes" | 4 | "bytes" |
5 | + "encoding/json" | ||
5 | "fmt" | 6 | "fmt" |
6 | "opp/controllers" | 7 | "opp/controllers" |
8 | + "opp/internal/aliyun" | ||
7 | "opp/protocol" | 9 | "opp/protocol" |
8 | "opp/services/upload" | 10 | "opp/services/upload" |
9 | 11 | ||
@@ -94,3 +96,24 @@ func (this *UploadController) Video() { | @@ -94,3 +96,24 @@ func (this *UploadController) Video() { | ||
94 | } | 96 | } |
95 | msg = protocol.NewReturnResponse(rsp, err) | 97 | msg = protocol.NewReturnResponse(rsp, err) |
96 | } | 98 | } |
99 | + | ||
100 | +//创建视频上传凭证 CreateUploadVideo | ||
101 | +// @router /createUploadVideo [post] | ||
102 | +func (this *UploadController) CreateUploadVideo() { | ||
103 | + var msg *protocol.ResponseMessage | ||
104 | + defer func() { | ||
105 | + this.Resp(msg) | ||
106 | + }() | ||
107 | + var request *aliyun.CreateUploadVideoRequest | ||
108 | + if err := json.Unmarshal(this.ByteBody, &request); err != nil { | ||
109 | + log.Error(err) | ||
110 | + msg = protocol.BadRequestParam(1) | ||
111 | + return | ||
112 | + } | ||
113 | + if b, m := this.Valid(request); !b { | ||
114 | + msg = m | ||
115 | + return | ||
116 | + } | ||
117 | + header := controllers.GetRequestHeader(this.Ctx) | ||
118 | + msg = protocol.NewReturnResponse(upload.CreateUploadVideo(header, request)) | ||
119 | +} |
@@ -3,6 +3,7 @@ module opp | @@ -3,6 +3,7 @@ module opp | ||
3 | go 1.12 | 3 | go 1.12 |
4 | 4 | ||
5 | require ( | 5 | require ( |
6 | + github.com/aliyun/alibaba-cloud-sdk-go v1.60.348 | ||
6 | github.com/astaxie/beego v1.10.0 | 7 | github.com/astaxie/beego v1.10.0 |
7 | github.com/disintegration/imaging v1.6.2 | 8 | github.com/disintegration/imaging v1.6.2 |
8 | github.com/go-sql-driver/mysql v1.4.1 | 9 | github.com/go-sql-driver/mysql v1.4.1 |
internal/aliyun/const.go
0 → 100644
internal/aliyun/struct.go
0 → 100644
1 | +package aliyun | ||
2 | + | ||
3 | +//创建视频上传凭证 | ||
4 | +/*CreateUploadVideo */ | ||
5 | +type CreateUploadVideoRequest struct { | ||
6 | +} | ||
7 | + | ||
8 | +type CreateUploadVideoResponse struct { | ||
9 | + RequestId string `json:"requestId"` | ||
10 | + VideoId string `json:"videoId"` | ||
11 | + UploadAddress string `json:"uploadAddress"` | ||
12 | + UploadAuth string `json:"uploadAuth"` | ||
13 | +} | ||
14 | + | ||
15 | +/*GetPlayInfo 获取播放信息*/ | ||
16 | +type GetPlayInfoRequest struct { | ||
17 | + VideoId string `json:"videoId" xml:"VideoId"` | ||
18 | +} | ||
19 | + | ||
20 | +// GetPlayInfoResponse is the response struct for api GetPlayInfo | ||
21 | +type GetPlayInfoResponse struct { | ||
22 | + //*responses.BaseResponse | ||
23 | + //RequestId string `json:"RequestId" xml:"RequestId"` | ||
24 | + VideoBase VideoBase `json:"VideoBase" xml:"VideoBase"` | ||
25 | + PlayInfoList PlayInfoListInGetPlayInfo `json:"PlayInfoList" xml:"PlayInfoList"` | ||
26 | +} | ||
27 | + | ||
28 | +// VideoBase is a nested struct in vod response | ||
29 | +type VideoBase struct { | ||
30 | + OutputType string `json:"OutputType" xml:"OutputType"` | ||
31 | + CoverURL string `json:"CoverURL" xml:"CoverURL"` | ||
32 | + Duration string `json:"Duration" xml:"Duration"` | ||
33 | + Status string `json:"Status" xml:"Status"` | ||
34 | + Title string `json:"Title" xml:"Title"` | ||
35 | + VideoId string `json:"VideoId" xml:"VideoId"` | ||
36 | + MediaType string `json:"MediaType" xml:"MediaType"` | ||
37 | + CreationTime string `json:"CreationTime" xml:"CreationTime"` | ||
38 | + TranscodeMode string `json:"TranscodeMode" xml:"TranscodeMode"` | ||
39 | + //ThumbnailList ThumbnailListInGetPlayInfo `json:"ThumbnailList" xml:"ThumbnailList"` | ||
40 | +} | ||
41 | + | ||
42 | +type PlayInfoListInGetPlayInfo struct { | ||
43 | + PlayInfo []PlayInfo `json:"PlayInfo" xml:"PlayInfo"` | ||
44 | +} | ||
45 | + | ||
46 | +// PlayInfo is a nested struct in vod response | ||
47 | +type PlayInfo struct { | ||
48 | + JobId string `json:"JobId" xml:"JobId"` | ||
49 | + Format string `json:"Format" xml:"Format"` | ||
50 | + PreprocessStatus string `json:"PreprocessStatus" xml:"PreprocessStatus"` | ||
51 | + EncryptType string `json:"EncryptType" xml:"EncryptType"` | ||
52 | + Fps string `json:"Fps" xml:"Fps"` | ||
53 | + ModificationTime string `json:"ModificationTime" xml:"ModificationTime"` | ||
54 | + NarrowBandType string `json:"NarrowBandType" xml:"NarrowBandType"` | ||
55 | + Bitrate string `json:"Bitrate" xml:"Bitrate"` | ||
56 | + Encrypt int64 `json:"Encrypt" xml:"Encrypt"` | ||
57 | + Rand string `json:"Rand" xml:"Rand"` | ||
58 | + CreationTime string `json:"CreationTime" xml:"CreationTime"` | ||
59 | + StreamType string `json:"StreamType" xml:"StreamType"` | ||
60 | + Height int64 `json:"Height" xml:"Height"` | ||
61 | + WatermarkId string `json:"WatermarkId" xml:"WatermarkId"` | ||
62 | + Duration string `json:"Duration" xml:"Duration"` | ||
63 | + Complexity string `json:"Complexity" xml:"Complexity"` | ||
64 | + Width int64 `json:"Width" xml:"Width"` | ||
65 | + Size int64 `json:"Size" xml:"Size"` | ||
66 | + Status string `json:"Status" xml:"Status"` | ||
67 | + Definition string `json:"Definition" xml:"Definition"` | ||
68 | + Plaintext string `json:"Plaintext" xml:"Plaintext"` | ||
69 | + PlayURL string `json:"PlayURL" xml:"PlayURL"` | ||
70 | + Specification string `json:"Specification" xml:"Specification"` | ||
71 | +} |
internal/aliyun/vod.go
0 → 100644
1 | +package aliyun | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "github.com/aliyun/alibaba-cloud-sdk-go/sdk" | ||
6 | + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" | ||
7 | + "github.com/aliyun/alibaba-cloud-sdk-go/services/vod" | ||
8 | + "github.com/astaxie/beego" | ||
9 | + "gitlab.fjmaimaimai.com/mmm-go/gocomm/common" | ||
10 | + comm_time "gitlab.fjmaimaimai.com/mmm-go/gocomm/time" | ||
11 | + "path" | ||
12 | + "time" | ||
13 | +) | ||
14 | + | ||
15 | +//客户端 | ||
16 | +func DefaultVodClient() (client *vod.Client, err error) { | ||
17 | + return InitVodClient(AccessKeyID, AccessKeySecret) | ||
18 | +} | ||
19 | + | ||
20 | +//初始化客户端 | ||
21 | +func InitVodClient(accessKeyId string, accessKeySecret string) (client *vod.Client, err error) { | ||
22 | + // 点播服务接入区域 | ||
23 | + regionId := RegionID | ||
24 | + // 创建授权对象 | ||
25 | + credential := &credentials.AccessKeyCredential{ | ||
26 | + accessKeyId, | ||
27 | + accessKeySecret, | ||
28 | + } | ||
29 | + // 自定义config | ||
30 | + config := sdk.NewConfig() | ||
31 | + config.AutoRetry = true // 失败是否自动重试 | ||
32 | + config.MaxRetryTime = 3 // 最大重试次数 | ||
33 | + config.Timeout = 3000000000 // 连接超时,单位:纳秒;默认为3秒 | ||
34 | + // 创建vodClient实例 | ||
35 | + return vod.NewClientWithOptions(regionId, config, credential) | ||
36 | +} | ||
37 | + | ||
38 | +//获取视频上传地址和凭证,并创建视频信息 | ||
39 | +func CreateUploadVideo(client *vod.Client) (response *CreateUploadVideoResponse, err error) { | ||
40 | + request := vod.CreateCreateUploadVideoRequest() | ||
41 | + request.Title = getFileName(FileVideo, "video_file.mp4") | ||
42 | + request.FileName = getFileName(FileVideo, "video_file.mp4") | ||
43 | + //request.CoverURL = "http://img.alicdn.com/tps/TB1qnJ1PVXXXXXCXXXXXXXXXXXX-700-700.png" | ||
44 | + //request.Tags = "tag1,tag2" | ||
45 | + request.AcceptFormat = "JSON" | ||
46 | + rsp, err := client.CreateUploadVideo(request) | ||
47 | + if err != nil { | ||
48 | + return | ||
49 | + } | ||
50 | + response = &CreateUploadVideoResponse{ | ||
51 | + RequestId: rsp.RequestId, | ||
52 | + VideoId: rsp.VideoId, | ||
53 | + UploadAddress: rsp.UploadAddress, | ||
54 | + UploadAuth: rsp.UploadAuth, | ||
55 | + } | ||
56 | + return | ||
57 | +} | ||
58 | + | ||
59 | +//获取播放信息 | ||
60 | +func GetPlayInfo(client *vod.Client, videoId string) (response *vod.GetPlayInfoResponse, err error) { | ||
61 | + request := vod.CreateGetPlayInfoRequest() | ||
62 | + request.VideoId = videoId | ||
63 | + request.AcceptFormat = "JSON" | ||
64 | + return client.GetPlayInfo(request) | ||
65 | +} | ||
66 | + | ||
67 | +//fileType: video voice image | ||
68 | +func getFileName(fileType string, filename string) string { | ||
69 | + date := comm_time.GetTimeByYyyymmdd() | ||
70 | + subfix := path.Ext(filename) | ||
71 | + prefix := fmt.Sprintf("%v_%v", time.Now().Unix(), common.RandomString(32)) | ||
72 | + filename = fmt.Sprintf("%v%v", prefix, subfix) | ||
73 | + sourcePath := fmt.Sprintf("%v/%v/%v/%v/%v", beego.BConfig.AppName, beego.BConfig.RunMode, fileType, date, filename) | ||
74 | + return sourcePath | ||
75 | +} |
1 | package utils | 1 | package utils |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "bytes" | ||
5 | + "encoding/gob" | ||
4 | "encoding/json" | 6 | "encoding/json" |
5 | "errors" | 7 | "errors" |
6 | "fmt" | 8 | "fmt" |
@@ -85,3 +87,12 @@ func JsonUnmarshal(jsonData string, v interface{}) { | @@ -85,3 +87,12 @@ func JsonUnmarshal(jsonData string, v interface{}) { | ||
85 | log.Error("json.unmarshal error data:", jsonData, e) | 87 | log.Error("json.unmarshal error data:", jsonData, e) |
86 | } | 88 | } |
87 | } | 89 | } |
90 | + | ||
91 | +//深度拷贝 | ||
92 | +func DeepCopy(dst, src interface{}) error { | ||
93 | + var buf bytes.Buffer | ||
94 | + if err := gob.NewEncoder(&buf).Encode(src); err != nil { | ||
95 | + return err | ||
96 | + } | ||
97 | + return gob.NewDecoder(&buf).Decode(dst) | ||
98 | +} |
internal/utils/utils_test.go
0 → 100644
1 | +package utils | ||
2 | + | ||
3 | +import "testing" | ||
4 | + | ||
5 | +func Test_DeepCopy(t *testing.T) { | ||
6 | + type User1 struct { | ||
7 | + Name string | ||
8 | + Age int | ||
9 | + Address string | ||
10 | + } | ||
11 | + type User2 struct { | ||
12 | + Name string | ||
13 | + Age int | ||
14 | + Job string | ||
15 | + } | ||
16 | + var src = User1{Name: "foo", Age: 10, Address: "bar"} | ||
17 | + var dst *User2 | ||
18 | + if err := DeepCopy(&dst, src); err != nil { | ||
19 | + t.Fatal(err) | ||
20 | + } | ||
21 | + if src.Name != dst.Name { | ||
22 | + t.Fatal("deep copy fail.") | ||
23 | + } | ||
24 | + //t.Log(src,"\n",dst) | ||
25 | +} |
@@ -393,6 +393,14 @@ func init() { | @@ -393,6 +393,14 @@ func init() { | ||
393 | 393 | ||
394 | beego.GlobalControllerRouter["opp/controllers/v1:UploadController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:UploadController"], | 394 | beego.GlobalControllerRouter["opp/controllers/v1:UploadController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:UploadController"], |
395 | beego.ControllerComments{ | 395 | beego.ControllerComments{ |
396 | + Method: "CreateUploadVideo", | ||
397 | + Router: `/createUploadVideo`, | ||
398 | + AllowHTTPMethods: []string{"post"}, | ||
399 | + MethodParams: param.Make(), | ||
400 | + Params: nil}) | ||
401 | + | ||
402 | + beego.GlobalControllerRouter["opp/controllers/v1:UploadController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:UploadController"], | ||
403 | + beego.ControllerComments{ | ||
396 | Method: "Image", | 404 | Method: "Image", |
397 | Router: `/image`, | 405 | Router: `/image`, |
398 | AllowHTTPMethods: []string{"post"}, | 406 | AllowHTTPMethods: []string{"post"}, |
@@ -23,6 +23,7 @@ func init() { | @@ -23,6 +23,7 @@ func init() { | ||
23 | beego.NSNamespace("message", beego.NSBefore(controllers.FilterComm), beego.NSInclude(&v1.MessageController{})), | 23 | beego.NSNamespace("message", beego.NSBefore(controllers.FilterComm), beego.NSInclude(&v1.MessageController{})), |
24 | beego.NSNamespace("department", beego.NSBefore(controllers.FilterComm), beego.NSInclude(&v1.DepartmentController{})), | 24 | beego.NSNamespace("department", beego.NSBefore(controllers.FilterComm), beego.NSInclude(&v1.DepartmentController{})), |
25 | beego.NSNamespace("config", beego.NSBefore(controllers.FilterComm), beego.NSInclude(&v1.ConfigController{})), | 25 | beego.NSNamespace("config", beego.NSBefore(controllers.FilterComm), beego.NSInclude(&v1.ConfigController{})), |
26 | + beego.NSNamespace("file", beego.NSBefore(controllers.FilterComm), beego.NSInclude(&v1.FileController{})), | ||
26 | ) | 27 | ) |
27 | beego.AddNamespace(nsV1) | 28 | beego.AddNamespace(nsV1) |
28 | 29 |
services/file/vod.go
0 → 100644
1 | +package file | ||
2 | + | ||
3 | +import ( | ||
4 | + "github.com/prometheus/common/log" | ||
5 | + "opp/internal/aliyun" | ||
6 | + "opp/internal/utils" | ||
7 | + "opp/protocol" | ||
8 | +) | ||
9 | + | ||
10 | +//GetPlayInfo 获取播放信息 | ||
11 | +func GetPlayInfo(header *protocol.RequestHeader, request *aliyun.GetPlayInfoRequest) (rsp *aliyun.GetPlayInfoResponse, err error) { | ||
12 | + var () | ||
13 | + client, e := aliyun.DefaultVodClient() | ||
14 | + if e != nil { | ||
15 | + log.Error(e) | ||
16 | + err = e | ||
17 | + return | ||
18 | + } | ||
19 | + response, e := aliyun.GetPlayInfo(client, request.VideoId) | ||
20 | + if e != nil { | ||
21 | + log.Error(e) | ||
22 | + err = e | ||
23 | + return | ||
24 | + } | ||
25 | + rsp = &aliyun.GetPlayInfoResponse{} | ||
26 | + if err = utils.DeepCopy(&rsp, response); err != nil { | ||
27 | + log.Error(err) | ||
28 | + return | ||
29 | + } | ||
30 | + return | ||
31 | +} |
@@ -5,6 +5,7 @@ import ( | @@ -5,6 +5,7 @@ import ( | ||
5 | "github.com/disintegration/imaging" | 5 | "github.com/disintegration/imaging" |
6 | "io" | 6 | "io" |
7 | "mime/multipart" | 7 | "mime/multipart" |
8 | + "opp/internal/aliyun" | ||
8 | "os" | 9 | "os" |
9 | "path" | 10 | "path" |
10 | "path/filepath" | 11 | "path/filepath" |
@@ -133,3 +134,16 @@ func GetSortFileKeys(files map[string][]*multipart.FileHeader) (keys []string) { | @@ -133,3 +134,16 @@ func GetSortFileKeys(files map[string][]*multipart.FileHeader) (keys []string) { | ||
133 | sort.Strings(keys) | 134 | sort.Strings(keys) |
134 | return | 135 | return |
135 | } | 136 | } |
137 | + | ||
138 | +//创建视频上传凭证 | ||
139 | +func CreateUploadVideo(header *protocol.RequestHeader, request *aliyun.CreateUploadVideoRequest) (rsp *aliyun.CreateUploadVideoResponse, err error) { | ||
140 | + var () | ||
141 | + client, e := aliyun.DefaultVodClient() | ||
142 | + if e != nil { | ||
143 | + log.Error(e) | ||
144 | + err = e | ||
145 | + return | ||
146 | + } | ||
147 | + rsp, err = aliyun.CreateUploadVideo(client) | ||
148 | + return | ||
149 | +} |
-
请 注册 或 登录 后发表评论