diff --git a/Dockerfile b/Dockerfile index d7197d5..b744711 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,11 @@ FROM golang:1.18.2-alpine AS builder MAINTAINER "Sigrid Jin From SOPT 30th Deliverble" +# install dependencies +RUN apk update && apk add --no-cache \ + alpine-sdk \ + ffmpeg + ENV GO111MODULE=on \ CGO_ENABLED=0 \ GOOS=linux \ @@ -14,6 +19,9 @@ COPY go.sum ./ RUN go mod download COPY . ./ +# test only ./test/FFMpegConvert_test.go +RUN go test -v ./test/FFMpegConvert_test.go + RUN go build deliverble-recording-msa/server/s3_server EXPOSE 8020 diff --git a/go.sum b/go.sum index 5338748..f3960a5 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,7 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/aws/aws-sdk-go v1.38.20/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.44.142 h1:KZ1/FDwCSft1DuNllFaBtWpcG0CW2NgQjvOrE1TdlXE= github.com/aws/aws-sdk-go v1.44.142/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.17.1 h1:02c72fDJr87N8RAC2s3Qu0YuvMRZKNZJ9F+lAehCazk= @@ -93,19 +94,25 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/floostack/transcoder v1.1.1 h1:ApvdTZGt4r1N8dcT1PEl4jxX5OBHaOMY42kmCKNbYCE= +github.com/floostack/transcoder v1.1.1/go.mod h1:lT+f8NEGaHP6AVeYLicas0EI0+TforD+DRuLziJg6bY= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -151,6 +158,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -165,6 +173,7 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -173,6 +182,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaW github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -183,8 +193,10 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -204,11 +216,16 @@ github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHR github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/onsi/ginkgo v1.15.2 h1:l77YT15o814C2qVL47NOyjV/6RbaP7kKdrvZnxQ3Org= github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/panjf2000/ants/v2 v2.4.2/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= @@ -219,6 +236,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -227,6 +245,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -236,6 +255,10 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/swaggest/assertjson v1.7.0 h1:SKw5Rn0LQs6UvmGrIdaKQbMR1R3ncXm5KNon+QJ7jtw= github.com/swaggest/assertjson v1.7.0/go.mod h1:vxMJMehbSVJd+dDWFCKv3QRZKNTpy/ktZKTz9LOEDng= +github.com/u2takey/ffmpeg-go v0.4.1 h1:l5ClIwL3N2LaH1zF3xivb3kP2HW95eyG5xhHE1JdZ9Y= +github.com/u2takey/ffmpeg-go v0.4.1/go.mod h1:ruZWkvC1FEiUNjmROowOAps3ZcWxEiOpFoHCvk97kGc= +github.com/u2takey/go-utils v0.3.1 h1:TaQTgmEZZeDHQFYfd+AdUT1cT4QJgJn/XVPELhHw4ys= +github.com/u2takey/go-utils v0.3.1/go.mod h1:6e+v5vEZ/6gu12w/DC2ixZdZtCrNokVxD0JUklcqdCs= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= @@ -264,6 +287,7 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +gocv.io/x/gocv v0.25.0/go.mod h1:Rar2PS6DV+T4FL+PM535EImD/h13hGVaHhnCu1xarBs= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -285,6 +309,7 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -335,6 +360,7 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -387,6 +413,7 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -421,6 +448,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -579,6 +607,7 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -595,3 +624,4 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/preprocess/registry.go b/preprocess/registry.go index f790ce7..cee389b 100644 --- a/preprocess/registry.go +++ b/preprocess/registry.go @@ -7,6 +7,7 @@ import ( recordingpb "deliverble-recording-msa/protos/v1/recording" userpb "deliverble-recording-msa/protos/v1/user" "deliverble-recording-msa/server/s3_server/client" + ffw "deliverble-recording-msa/server/s3_server/client" "fmt" _ "github.com/aws/aws-sdk-go-v2/aws" _ "github.com/aws/aws-sdk-go-v2/config" @@ -25,6 +26,7 @@ import ( "log" "net/http" "os" + "strings" "time" ) @@ -176,6 +178,134 @@ func (s *S3Server) UploadRecording(_ context.Context, req *recordingpb.UploadRec } } +func (s *S3Server) UploadRecordingV2(_ context.Context, req *recordingpb.UploadRecordingRequest) (*recordingpb.UploadRecordingResponse, error) { + err := godotenv.Load(".env") + if err != nil { + log.Fatal("Error loading .env file") + } + info := client.S3Info{ + AwsS3Region: os.Getenv("AP_NORTHEAST_2"), + BucketName: os.Getenv("DELIVERBLE_BUCKET_NAME"), + AwsAccessKey: os.Getenv("DELIVERBLE_ACCESS_KEY"), + AwsSecretKey: os.Getenv("DELIVERBLE_SECRET_KEY"), + } + + client, err := info.InitS3DefaultConfig() + if err != nil { + log.Println(err) + return nil, err + } + log.Println("S3 client init success ::::::::::::: ", client) + + // 0. work with given uploaded file + filename := fmt.Sprintf("%v.mp3", time.Now().Unix()) + filepath := "/tmp/" + filename + + err = ioutil.WriteFile(filepath, req.Recording, 0644) + if err != nil { + log.Println("Error writing to file: ", err) + return nil, err + } + + // 1. change `uploaded` mp3 file to webm file + fileNameWebm, errChange := ffw.ChangeFileNameMp3ToWebm(filepath) + if errChange != nil { + log.Println("UploadRecordingV2 Error ::::::: ", errChange) + response := &recordingpb.UploadRecordingResponse{ + Result: false, + Url: "", + Key: "", + } + return response, err + } + filename = *fileNameWebm + + // 2. convert converted `.webm` file to `.mp3` file + // filename to remove `.mp3` but not to add `.webm` + errConvert := ffw.ConvertWebmBlobToMp3File(strings.Replace(filename, ".mp3", "", -1)) + if errConvert != nil { + log.Println("UploadRecordingV2 Error ::::::: ", errConvert) + response := &recordingpb.UploadRecordingResponse{ + Result: false, + Url: "", + Key: "", + } + return response, err + } + + var response *recordingpb.UploadRecordingResponse + recording, err := info.UploadRecordingV2(filename, filepath) + if err != nil { + response = &recordingpb.UploadRecordingResponse{ + Result: false, + Url: "", + Key: "", + } + return response, err + } else { + response = &recordingpb.UploadRecordingResponse{ + Result: true, + Url: recording.Location, + Key: *recording.Key, + } + return response, nil + } +} + +func UploadRecordingHandlerV2(c echo.Context) error { + file, err := c.FormFile("file") // file : "file" parsing + if err != nil { + c.JSON(http.StatusBadRequest, err) + return err + } + + src, err := file.Open() // file api open + if err != nil { + log.Println("Error opening file: ", err) + err := c.JSON(http.StatusInternalServerError, err) + if err != nil { + c.JSON(http.StatusInternalServerError, err) + return err + } + return err + } + + defer src.Close() + buffer := make([]byte, file.Size) // file size buf define + _, err = src.Read(buffer) + if err != nil { + c.JSON(http.StatusInternalServerError, err) + return err + } // file read + + ctx := context.Background() + + conn, err := grpc.Dial("localhost:8020", grpc.WithInsecure()) + if err != nil { + log.Println(err) + return c.JSON(http.StatusInternalServerError, nil) + } + + taskClient := recordingpb.NewRecordingTaskClient(conn) + r, err := taskClient.UploadRecordingV2(ctx, &recordingpb.UploadRecordingRequest{Recording: buffer}) + + if err != nil { + log.Println(err) + return c.JSON(http.StatusInternalServerError, nil) + } + + if r.Result == false { + return c.JSON(http.StatusInternalServerError, r) + } + + successResponse := &client.UploadRecordingHandlerResponse{ + Code: http.StatusCreated, + Url: r.Url, + Key: r.Key, + } + return c.JSON(http.StatusCreated, successResponse) +} + func UploadRecordingHandler(c echo.Context) error { file, err := c.FormFile("file") // file : "file" parsing if err != nil { diff --git a/protos/v1/recording/recording.pb.go b/protos/v1/recording/recording.pb.go index 340bb29..f1e8ec3 100644 --- a/protos/v1/recording/recording.pb.go +++ b/protos/v1/recording/recording.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 -// protoc v3.21.4 +// protoc v3.21.12 // source: protos/v1/recording/recording.proto package deliverble_recording_microservice @@ -146,18 +146,25 @@ var file_protos_v1_recording_recording_proto_rawDesc = []byte{ 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x32, 0x76, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, - 0x67, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x12, 0x64, 0x0a, 0x0f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x64, - 0x2e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x2e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x39, 0x5a, 0x37, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x65, 0x6c, 0x69, 0x76, - 0x65, 0x72, 0x42, 0x6c, 0x65, 0x2f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x62, 0x6c, 0x65, - 0x2d, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x69, 0x63, 0x72, 0x6f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x03, 0x6b, 0x65, 0x79, 0x32, 0xde, 0x01, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x12, 0x64, 0x0a, 0x0f, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, + 0x64, 0x2e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x2e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, + 0x11, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, + 0x56, 0x32, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x2e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, 0x6f, + 0x64, 0x2e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x42, 0x6c, 0x65, 0x2f, 0x64, + 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -179,9 +186,11 @@ var file_protos_v1_recording_recording_proto_goTypes = []interface{}{ } var file_protos_v1_recording_recording_proto_depIdxs = []int32{ 0, // 0: prod.recording.recording_task.UploadRecording:input_type -> prod.recording.UploadRecordingRequest - 1, // 1: prod.recording.recording_task.UploadRecording:output_type -> prod.recording.UploadRecordingResponse - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type + 0, // 1: prod.recording.recording_task.UploadRecordingV2:input_type -> prod.recording.UploadRecordingRequest + 1, // 2: prod.recording.recording_task.UploadRecording:output_type -> prod.recording.UploadRecordingResponse + 1, // 3: prod.recording.recording_task.UploadRecordingV2:output_type -> prod.recording.UploadRecordingResponse + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/protos/v1/recording/recording.proto b/protos/v1/recording/recording.proto index af44459..f3cb2fe 100644 --- a/protos/v1/recording/recording.proto +++ b/protos/v1/recording/recording.proto @@ -6,6 +6,7 @@ option go_package = "github.com/DeliverBle/deliverble-recording-microservice"; service recording_task { rpc UploadRecording (UploadRecordingRequest) returns (UploadRecordingResponse) {} + rpc UploadRecordingV2 (UploadRecordingRequest) returns (UploadRecordingResponse) {} } // UploadRecordingRequest wrapped with byte data diff --git a/protos/v1/recording/recording_grpc.pb.go b/protos/v1/recording/recording_grpc.pb.go index da54a94..5128422 100644 --- a/protos/v1/recording/recording_grpc.pb.go +++ b/protos/v1/recording/recording_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 -// - protoc v3.21.4 +// - protoc v3.21.12 // source: protos/v1/recording/recording.proto package deliverble_recording_microservice @@ -23,6 +23,7 @@ const _ = grpc.SupportPackageIsVersion7 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type RecordingTaskClient interface { UploadRecording(ctx context.Context, in *UploadRecordingRequest, opts ...grpc.CallOption) (*UploadRecordingResponse, error) + UploadRecordingV2(ctx context.Context, in *UploadRecordingRequest, opts ...grpc.CallOption) (*UploadRecordingResponse, error) } type recordingTaskClient struct { @@ -42,11 +43,21 @@ func (c *recordingTaskClient) UploadRecording(ctx context.Context, in *UploadRec return out, nil } +func (c *recordingTaskClient) UploadRecordingV2(ctx context.Context, in *UploadRecordingRequest, opts ...grpc.CallOption) (*UploadRecordingResponse, error) { + out := new(UploadRecordingResponse) + err := c.cc.Invoke(ctx, "/prod.recording.recording_task/UploadRecordingV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // RecordingTaskServer is the server API for RecordingTask service. // All implementations must embed UnimplementedRecordingTaskServer // for forward compatibility type RecordingTaskServer interface { UploadRecording(context.Context, *UploadRecordingRequest) (*UploadRecordingResponse, error) + UploadRecordingV2(context.Context, *UploadRecordingRequest) (*UploadRecordingResponse, error) mustEmbedUnimplementedRecordingTaskServer() } @@ -57,6 +68,9 @@ type UnimplementedRecordingTaskServer struct { func (UnimplementedRecordingTaskServer) UploadRecording(context.Context, *UploadRecordingRequest) (*UploadRecordingResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UploadRecording not implemented") } +func (UnimplementedRecordingTaskServer) UploadRecordingV2(context.Context, *UploadRecordingRequest) (*UploadRecordingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UploadRecordingV2 not implemented") +} func (UnimplementedRecordingTaskServer) mustEmbedUnimplementedRecordingTaskServer() {} // UnsafeRecordingTaskServer may be embedded to opt out of forward compatibility for this service. @@ -88,6 +102,24 @@ func _RecordingTask_UploadRecording_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } +func _RecordingTask_UploadRecordingV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UploadRecordingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecordingTaskServer).UploadRecordingV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/prod.recording.recording_task/UploadRecordingV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecordingTaskServer).UploadRecordingV2(ctx, req.(*UploadRecordingRequest)) + } + return interceptor(ctx, in, info, handler) +} + // RecordingTask_ServiceDesc is the grpc.ServiceDesc for RecordingTask service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -99,6 +131,10 @@ var RecordingTask_ServiceDesc = grpc.ServiceDesc{ MethodName: "UploadRecording", Handler: _RecordingTask_UploadRecording_Handler, }, + { + MethodName: "UploadRecordingV2", + Handler: _RecordingTask_UploadRecordingV2_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "protos/v1/recording/recording.proto", diff --git a/server/s3_server/client/FFMpeg.go b/server/s3_server/client/FFMpeg.go new file mode 100644 index 0000000..58a63b0 --- /dev/null +++ b/server/s3_server/client/FFMpeg.go @@ -0,0 +1,47 @@ +package client + +import ( + "bytes" + "fmt" + "os" + "os/exec" + "regexp" +) + +func ChangeFileNameMp3ToWebm(inputFileName string) (*string, error) { + // Check if the input file exists + if _, err := os.Stat(inputFileName); os.IsNotExist(err) { + return nil, fmt.Errorf("file %s does not exist", inputFileName) + } + + // Use a regular expression to remove all instances of ".mp3" from the file name + r := regexp.MustCompile("\\.mp3") + outputFileName := r.ReplaceAllString(inputFileName, "") + + // Append the new extension to the file name + outputFileNameWithWebm := outputFileName + ".webm" + + // Rename the input file to the output file + err := os.Rename(inputFileName, outputFileNameWithWebm) + if err != nil { + return nil, fmt.Errorf("failed to rename file %s to %s: %v", inputFileName, outputFileNameWithWebm, err) + } + + return &outputFileName, nil +} + +func ConvertWebmBlobToMp3File(input string) error { + cmd := exec.Command("ffmpeg", "-i", input+".webm", input+".mp3") + var out bytes.Buffer + var stderr bytes.Buffer + cmd.Stdout = &out + cmd.Stderr = &stderr + err := cmd.Run() + if err != nil { + fmt.Println(fmt.Sprint(err) + ": " + stderr.String()) + return fmt.Errorf("ffmpeg command failed") + } + fmt.Println("Result: " + out.String()) + + return nil +} diff --git a/server/s3_server/client/S3Client.go b/server/s3_server/client/S3Client.go index cd75ced..0136110 100644 --- a/server/s3_server/client/S3Client.go +++ b/server/s3_server/client/S3Client.go @@ -31,7 +31,38 @@ func (s *S3Info) InitS3DefaultConfig() (*s3.Client, error) { } /* -UploadRecording : uploading process to deliverble s3 bucket when served by the main restful server +UploadRecordingV2 : uploading process to deliverble s3 bucket when served by the main restful server +*/ +func (s *S3Info) UploadRecordingV2(filename string, filepath string) (*manager.UploadOutput, error) { + uploader := manager.NewUploader(s.S3Client) + + // change filename to remove `/tmp` path location at the forehead of the name + filename = strings.TrimPrefix(filename, "/tmp/") + + // Add the ".mp3" extension to the file name + filename = strings.Join([]string{filename, ".mp3"}, "") + + // open file by filepath + file, err := os.Open(filepath) + if err != nil { + log.Println("UploadRecording File Open Error ::::::: ", err) + return nil, err + } + + result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ + Bucket: aws.String(s.BucketName), + Key: aws.String(filename), + Body: file, + }) + if err != nil { + log.Fatal("UploadRecording Error ::::::: ", err) + return nil, err + } + return result, nil +} + +/* +UploadRecordingV2 : uploading process to deliverble s3 bucket when served by the main restful server (with using ffmpeg to convert the file) */ func (s *S3Info) UploadRecording(filename string, filepath string) (*manager.UploadOutput, error) { uploader := manager.NewUploader(s.S3Client) @@ -39,7 +70,7 @@ func (s *S3Info) UploadRecording(filename string, filepath string) (*manager.Upl // open file by filepath file, err := os.Open(filepath) if err != nil { - log.Fatal("UploadRecording File Open Error ::::::: ", err) + log.Println("UploadRecording File Open Error ::::::: ", err) return nil, err } diff --git a/server/s3_server/main.go b/server/s3_server/main.go index f2bf36a..ba4dc81 100644 --- a/server/s3_server/main.go +++ b/server/s3_server/main.go @@ -31,6 +31,7 @@ func main() { go func() { e := echo.New() + e.POST("/upload/v2", preprocess.UploadRecordingHandlerV2) e.POST("/upload", preprocess.UploadRecordingHandler) err := e.Start(":8000") if err != nil { diff --git a/test/FFMpegConvert_test.go b/test/FFMpegConvert_test.go new file mode 100644 index 0000000..a8947c3 --- /dev/null +++ b/test/FFMpegConvert_test.go @@ -0,0 +1,75 @@ +package test + +import ( + ffw "deliverble-recording-msa/server/s3_server/client" + "fmt" + "github.com/stretchr/testify/assert" + "io" + "os" + "testing" +) + +func copyFile(src, dst string) error { + // Open the source file for reading + srcFile, err := os.Open(src) + if err != nil { + return err + } + defer srcFile.Close() + + // Create the destination file + dstFile, err := os.Create(dst) + if err != nil { + return err + } + defer dstFile.Close() + + // Copy the contents of the source file to the destination file + _, err = io.Copy(dstFile, srcFile) + if err != nil { + return err + } + + return nil +} + +func TestFFMpegConvert(t *testing.T) { + // given: file name + Mp3Extension := ".mp3" + SampleSourceName := "test" // source mp3 + SrcName := "test2" // fake mp3 (copied from source mp3 for testing) + DstName := "output2" // real mp3 + + // given: copy test.mp3 to test2.mp3 + errCopy := copyFile(SampleSourceName+Mp3Extension, SrcName+Mp3Extension) + if errCopy != nil { + fmt.Println(errCopy) + } + assert.NoError(t, errCopy) + + assertions := assert.New(t) + if _, err := os.Stat(DstName + Mp3Extension); err == nil { + err = os.Remove(DstName + Mp3Extension) + assertions.NoError(err) + } + + // when: ChangeFileNameMp3ToWebm + outputFileNameWithWebM, errChange := ffw.ChangeFileNameMp3ToWebm(SrcName + Mp3Extension) + if errChange != nil { + fmt.Println(errChange) + assertions.Fail("failed to change file name : ", errChange.Error()) + } + + // when: ConvertWebmBlobToMp3File + errConvert := ffw.ConvertWebmBlobToMp3File(SrcName) + if errConvert != nil { + fmt.Println(errConvert) + assertions.Fail("ffmpeg command failed : ", errConvert.Error()) + } + + // then + assertions.NoError(errChange) + assertions.NoError(errConvert) + assertions.Equal(SrcName, *outputFileNameWithWebM) + assertions.FileExists(SrcName + Mp3Extension) +} diff --git a/test/UploadRecordingHandler_test.go b/test/UploadRecordingHandler_test.go index 73366a0..d756933 100644 --- a/test/UploadRecordingHandler_test.go +++ b/test/UploadRecordingHandler_test.go @@ -17,6 +17,54 @@ import ( "testing" ) +func TestUploadRecordingHandlerV2(t *testing.T) { + /* + Run `go build deliverble-recrording-msa/server/s3_server` before running this test. + */ + + // given : preparing form file (mp3) + assertions := assert.New(t) + + path := "./test.mp3" + file, err := os.Open(path) + assertions.NoError(err) + defer file.Close() + + buf := &bytes.Buffer{} + writer := multipart.NewWriter(buf) + + multi, err := writer.CreateFormFile("file", filepath.Base(path)) + assertions.NoError(err) + + _, err = io.Copy(multi, file) + assertions.NoError(err) + + err = writer.Close() + assertions.NoError(err) + + // when + res := httptest.NewRecorder() + req := httptest.NewRequest("POST", "/upload/v2", buf) + req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) + + // create new c echo.Context for testing + con := echo.New().NewContext(req, res) + + // then + err = preprocess.UploadRecordingHandler(con) + assertions.NoError(err) + + body, err := ioutil.ReadAll(res.Body) + assertions.NoError(err) + + var response client.UploadRecordingHandlerResponse + err = json.Unmarshal(body, &response) + + assert.Equal(t, http.StatusCreated, res.Code) + assert.Contains(t, response.Url, "https://deliverable-recording.s3.ap-northeast-2.amazonaws.com") + assert.Contains(t, response.Url, ".mp3") +} + func TestUploadRecordingHandler(t *testing.T) { /* Run `go build deliverble-recrording-msa/server/s3_server` before running this test. diff --git a/test/test.mp3 b/test/test.mp3 index cfa8654..6ed22d7 100644 Binary files a/test/test.mp3 and b/test/test.mp3 differ diff --git a/test/test2.mp3 b/test/test2.mp3 new file mode 100644 index 0000000..17a554d Binary files /dev/null and b/test/test2.mp3 differ diff --git a/test/test2.webm b/test/test2.webm new file mode 100644 index 0000000..6ed22d7 Binary files /dev/null and b/test/test2.webm differ