Commit fcf64ffa5e843bb47fc07cc0ed3ab8221d4d2123

Authored by Lawrence
1 parent 908145ce

修正音频编码判断代码错误,仅当存在AAC音轨时打开音频

web_src/src/components/gb28181/devicePlayer.vue
1 1 <template>
2   - <div id="devicePlayer">
3   - <el-dialog title="视频播放" top="0" :visible.sync="showVideoDialog" :destroy-on-close="true" @close="close()">
4   - <LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :hasaudio="hasaudio" fluent autoplay live ></LivePlayer>
5   - <div id="shared" style="text-align: right; margin-top: 1rem;">
6   - <el-tabs v-model="tabActiveName">
7   - <el-tab-pane label="媒体流信息" name="media">
8   - <div style="margin-bottom: 0.5rem;">
9   - <el-button type="primary" size="small" @click="playRecord(true, '')">播放</el-button>
10   - <el-button type="primary" size="small" @click="startRecord()">录制</el-button>
11   - <el-button type="primary" size="small" @click="stopRecord()">停止录制</el-button>
12   - </div>
13   - <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
14   - <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址:</span>
15   - <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedUrl)"></el-input>
16   - </div>
17   - <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
18   - <span style="width: 5rem; line-height: 2.5rem; text-align: right;">iframe:</span>
19   - <el-input v-model="getPlayerShared.sharedIframe" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedIframe)"></el-input>
20   - </div>
21   - <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
22   - <span style="width: 5rem; line-height: 2.5rem; text-align: right;">资源地址:</span>
23   - <el-input v-model="getPlayerShared.sharedRtmp" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedRtmp)"></el-input>
24   - </div>
25   - </el-tab-pane>
26   - <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
27   - <el-tab-pane label="录像查询" name="second">
28   - <el-date-picker v-model="videoHistory.startTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="开始时间"
29   - @change="recordList()"></el-date-picker>
30   - <el-date-picker v-model="videoHistory.endTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="结束时间"
31   - @change="recordList()"></el-date-picker>
32   - <el-table :data="videoHistory.searchHistoryResult" style="width: 100%">
33   - <el-table-column label="名称" prop="name" width="150"></el-table-column>
34   - <el-table-column label="文件" prop="filePath" width="300"></el-table-column>
35   - <el-table-column label="开始时间" prop="startTime" width="160"></el-table-column>
36   - <el-table-column label="结束时间" prop="endTime" width="160"></el-table-column>
  2 +<div id="devicePlayer">
  3 + <el-dialog title="视频播放" top="0" :visible.sync="showVideoDialog" :destroy-on-close="true" @close="close()">
  4 + <LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :hasaudio="hasaudio" fluent autoplay live></LivePlayer>
  5 + <div id="shared" style="text-align: right; margin-top: 1rem;">
  6 + <el-tabs v-model="tabActiveName">
  7 + <el-tab-pane label="媒体流信息" name="media">
  8 + <div style="margin-bottom: 0.5rem;">
  9 + <el-button type="primary" size="small" @click="playRecord(true, '')">播放</el-button>
  10 + <el-button type="primary" size="small" @click="startRecord()">录制</el-button>
  11 + <el-button type="primary" size="small" @click="stopRecord()">停止录制</el-button>
  12 + </div>
  13 + <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
  14 + <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址:</span>
  15 + <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedUrl)"></el-input>
  16 + </div>
  17 + <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
  18 + <span style="width: 5rem; line-height: 2.5rem; text-align: right;">iframe:</span>
  19 + <el-input v-model="getPlayerShared.sharedIframe" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedIframe)"></el-input>
  20 + </div>
  21 + <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
  22 + <span style="width: 5rem; line-height: 2.5rem; text-align: right;">资源地址:</span>
  23 + <el-input v-model="getPlayerShared.sharedRtmp" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedRtmp)"></el-input>
  24 + </div>
  25 + </el-tab-pane>
  26 + <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
  27 + <el-tab-pane label="录像查询" name="second">
  28 + <el-date-picker v-model="videoHistory.startTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="开始时间" @change="recordList()"></el-date-picker>
  29 + <el-date-picker v-model="videoHistory.endTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="结束时间" @change="recordList()"></el-date-picker>
  30 + <el-table :data="videoHistory.searchHistoryResult" style="width: 100%">
  31 + <el-table-column label="名称" prop="name" width="150"></el-table-column>
  32 + <el-table-column label="文件" prop="filePath" width="300"></el-table-column>
  33 + <el-table-column label="开始时间" prop="startTime" width="160"></el-table-column>
  34 + <el-table-column label="结束时间" prop="endTime" width="160"></el-table-column>
37 35  
38   - <el-table-column label="操作">
39   - <template slot-scope="scope">
40   - <el-button type="primary" size="mini" @click="playRecord(false, scope.row)">播放</el-button>
41   - </template>
42   - </el-table-column>
43   - </el-table>
44   - </el-tab-pane>
45   - <!--遥控界面-->
46   - <el-tab-pane label="云台控制" name="third">
47   - <div style="display: flex; justify-content: center;">
48   - <div class="control-wrapper">
49   - <div class="control-btn control-top" @mousedown="ptzCamera(0, 1, 0)" @mouseup="ptzCamera(0, 0, 0)">
50   - <i class="el-icon-caret-top"></i>
51   - <div class="control-inner-btn control-inner"></div>
52   - </div>
53   - <div class="control-btn control-left" @mousedown="ptzCamera(1, 0, 0)" @mouseup="ptzCamera(0, 0, 0)">
54   - <i class="el-icon-caret-left"></i>
55   - <div class="control-inner-btn control-inner"></div>
56   - </div>
57   - <div class="control-btn control-bottom" @mousedown="ptzCamera(0, 2, 0)" @mouseup="ptzCamera(0, 0, 0)">
58   - <i class="el-icon-caret-bottom"></i>
59   - <div class="control-inner-btn control-inner"></div>
60   - </div>
61   - <div class="control-btn control-right" @mousedown="ptzCamera(2, 0, 0)" @mouseup="ptzCamera(0, 0, 0)">
62   - <i class="el-icon-caret-right"></i>
63   - <div class="control-inner-btn control-inner"></div>
64   - </div>
65   - <div class="control-round">
66   - <div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>
67   - </div>
  36 + <el-table-column label="操作">
  37 + <template slot-scope="scope">
  38 + <el-button type="primary" size="mini" @click="playRecord(false, scope.row)">播放</el-button>
  39 + </template>
  40 + </el-table-column>
  41 + </el-table>
  42 + </el-tab-pane>
  43 + <!--遥控界面-->
  44 + <el-tab-pane label="云台控制" name="third">
  45 + <div style="display: flex; justify-content: center;">
  46 + <div class="control-wrapper">
  47 + <div class="control-btn control-top" @mousedown="ptzCamera(0, 1, 0)" @mouseup="ptzCamera(0, 0, 0)">
  48 + <i class="el-icon-caret-top"></i>
  49 + <div class="control-inner-btn control-inner"></div>
  50 + </div>
  51 + <div class="control-btn control-left" @mousedown="ptzCamera(1, 0, 0)" @mouseup="ptzCamera(0, 0, 0)">
  52 + <i class="el-icon-caret-left"></i>
  53 + <div class="control-inner-btn control-inner"></div>
  54 + </div>
  55 + <div class="control-btn control-bottom" @mousedown="ptzCamera(0, 2, 0)" @mouseup="ptzCamera(0, 0, 0)">
  56 + <i class="el-icon-caret-bottom"></i>
  57 + <div class="control-inner-btn control-inner"></div>
  58 + </div>
  59 + <div class="control-btn control-right" @mousedown="ptzCamera(2, 0, 0)" @mouseup="ptzCamera(0, 0, 0)">
  60 + <i class="el-icon-caret-right"></i>
  61 + <div class="control-inner-btn control-inner"></div>
  62 + </div>
  63 + <div class="control-round">
  64 + <div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>
  65 + </div>
68 66  
69   - <div style="position: absolute; left: 7.25rem; top: 1.25rem" @mousedown="ptzCamera(0, 0, 2)" @mouseup="ptzCamera(0, 0, 0)"><i
70   - class="el-icon-zoom-in" style="font-size: 1.875rem;"></i></div>
71   - <div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;" @mousedown="ptzCamera(0, 0, 1)"
72   - @mouseup="ptzCamera(0, 0, 0)"><i class="el-icon-zoom-out"></i></div>
73   - </div>
74   - </div>
  67 + <div style="position: absolute; left: 7.25rem; top: 1.25rem" @mousedown="ptzCamera(0, 0, 2)" @mouseup="ptzCamera(0, 0, 0)"><i class="el-icon-zoom-in" style="font-size: 1.875rem;"></i></div>
  68 + <div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;" @mousedown="ptzCamera(0, 0, 1)" @mouseup="ptzCamera(0, 0, 0)"><i class="el-icon-zoom-out"></i></div>
  69 + </div>
  70 + </div>
75 71  
76   - </el-tab-pane>
77   - </el-tabs>
78   - </div>
79   - </el-dialog>
80   - </div>
  72 + </el-tab-pane>
  73 + </el-tabs>
  74 + </div>
  75 + </el-dialog>
  76 +</div>
81 77 </template>
82 78  
83 79 <script>
84   - import LivePlayer from '@liveqing/liveplayer'
85   - export default {
86   - name: 'devicePlayer',
87   - props: {},
88   - components: {
89   - LivePlayer
90   - },
91   - computed: {
92   - getPlayerShared: function() {
  80 +import LivePlayer from '@liveqing/liveplayer'
  81 +export default {
  82 + name: 'devicePlayer',
  83 + props: {},
  84 + components: {
  85 + LivePlayer
  86 + },
  87 + computed: {
  88 + getPlayerShared: function () {
  89 + return {
  90 + sharedUrl: window.location.host + '/' + this.videoUrl,
  91 + sharedIframe: '<iframe src="' + window.location.host + '/' + this.videoUrl + '"></iframe>',
  92 + sharedRtmp: this.videoUrl
  93 + };
  94 + }
  95 + },
  96 + created() {
  97 + // this.videoHistory.searchHistoryResult = falsificationData.recordData.recordList;
  98 + },
  99 + data() {
93 100 return {
94   - sharedUrl: window.location.host + '/' + this.videoUrl,
95   - sharedIframe: '<iframe src="' + window.location.host + '/' + this.videoUrl + '"></iframe>',
96   - sharedRtmp: this.videoUrl
97   - };
98   - }
99   - },
100   - created() {
101   - // this.videoHistory.searchHistoryResult = falsificationData.recordData.recordList;
102   - },
103   - data() {
104   - return {
105   - video:'http://lndxyj.iqilu.com/public/upload/2019/10/14/8c001ea0c09cdc59a57829dabc8010fa.mp4',
106   - videoUrl: '',
107   - videoHistory: {
108   - startTime: '',
109   - endTime: '',
110   - searchHistoryResult: [] //媒体流历史记录搜索结果
111   - },
112   - showVideoDialog: false,
113   - normalssrc: '',
114   - ssrc: '',
115   - deviceId: '',
116   - channelId: '',
117   - tabActiveName: 'media',
118   - hasaudio: false
  101 + video: 'http://lndxyj.iqilu.com/public/upload/2019/10/14/8c001ea0c09cdc59a57829dabc8010fa.mp4',
  102 + videoUrl: '',
  103 + videoHistory: {
  104 + startTime: '',
  105 + endTime: '',
  106 + searchHistoryResult: [] //媒体流历史记录搜索结果
  107 + },
  108 + showVideoDialog: false,
  109 + normalssrc: '',
  110 + ssrc: '',
  111 + deviceId: '',
  112 + channelId: '',
  113 + tabActiveName: 'media',
  114 + hasaudio: false
119 115  
120   - };
121   - },
122   - methods: {
  116 + };
  117 + },
  118 + methods: {
123 119  
124   - play: function(streamInfo, deviceId, channelId, hasAudio) {
125   - this.hasaudio = hasAudio;
126   - // 根据媒体流信息二次判断
127   - if( this.hasaudio && !!streamInfo.tracks && streamInfo.tracks.length > 0) {
128   - var realHasAudio = false;
129   - for (let i = 0; i < streamInfo.tracks; i++) {
130   - if (streamInfo.tracks[i].codec_type == 1) { // 判断为音频
131   - realHasAudio = true;
  120 + play: function (streamInfo, deviceId, channelId, hasAudio) {
  121 + this.hasaudio = hasAudio;
  122 + // 根据媒体流信息二次判断
  123 + if (!!streamInfo.tracks && streamInfo.tracks.length > 0) {
  124 + var realHasAudio = false;
  125 + for (let i = 0; i < streamInfo.tracks.length; i++) {
  126 + if (streamInfo.tracks[i].codec_type == 1 && streamInfo.tracks[i].codec_id_name == "CodecAAC") { // 判断为AAC音频
  127 + realHasAudio = true;
  128 + }
  129 + }
  130 + this.hasaudio = realHasAudio; //&& this.hasaudio;
132 131 }
133   - }
134   - this.hasaudio = realHasAudio && this.hasaudio;
135   - }
136   - this.ssrc = streamInfo.ssrc;
137   - this.deviceId = deviceId;
138   - this.channelId = channelId;
139   - // this.$refs.videoPlayer.hasaudio = hasAudio;
140   - // this.videoUrl = streamInfo.flv + "?" + new Date().getTime();
141   - this.videoUrl = streamInfo.ws_flv;
142   - this.showVideoDialog = true;
143   - console.log(this.ssrc);
144   - },
145   - close: function() {
146   - console.log('关闭视频');
147   - this.$refs.videoPlayer.pause();
148   - this.videoUrl = '';
149   - this.showVideoDialog = false;
150   - },
151   - copySharedInfo: function(data) {
152   - console.log('复制内容:' + data);
153   - let _this = this;
154   - this.$copyText(data).then(
155   - function(e) {
156   - _this.$message({
157   - showClose: true,
158   - message: '复制成功',
159   - type: 'success'
160   - });
161   - },
162   - function(e) {
163   - _this.$message({
164   - showClose: true,
165   - message: '复制失败,请手动复制',
166   - type: 'error'
167   - });
168   - }
169   - );
170   - },
  132 + this.ssrc = streamInfo.ssrc;
  133 + this.deviceId = deviceId;
  134 + this.channelId = channelId;
  135 + // this.$refs.videoPlayer.hasaudio = hasAudio;
  136 + // this.videoUrl = streamInfo.flv + "?" + new Date().getTime();
  137 + this.videoUrl = streamInfo.ws_flv;
  138 + this.showVideoDialog = true;
  139 + console.log(this.ssrc);
  140 + },
  141 + close: function () {
  142 + console.log('关闭视频');
  143 + this.$refs.videoPlayer.pause();
  144 + this.videoUrl = '';
  145 + this.showVideoDialog = false;
  146 + },
  147 + copySharedInfo: function (data) {
  148 + console.log('复制内容:' + data);
  149 + let _this = this;
  150 + this.$copyText(data).then(
  151 + function (e) {
  152 + _this.$message({
  153 + showClose: true,
  154 + message: '复制成功',
  155 + type: 'success'
  156 + });
  157 + },
  158 + function (e) {
  159 + _this.$message({
  160 + showClose: true,
  161 + message: '复制失败,请手动复制',
  162 + type: 'error'
  163 + });
  164 + }
  165 + );
  166 + },
171 167  
172   - recordList: function() {
173   - if (!this.videoHistory.startTime || !this.videoHistory.endTime) {
174   - return;
175   - }
176   - let that = this;
177   - this.$axios({
178   - method: 'get',
179   - url: '/api/record/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.videoHistory
180   - .startTime + '&endTime=' + this.videoHistory.endTime
181   - }).then(function(res) {
182   - console.log(JSON.stringify(res));
183   - }).catch(function(e) {
184   - // that.videoHistory.searchHistoryResult = falsificationData.recordData;
185   - });
  168 + recordList: function () {
  169 + if (!this.videoHistory.startTime || !this.videoHistory.endTime) {
  170 + return;
  171 + }
  172 + let that = this;
  173 + this.$axios({
  174 + method: 'get',
  175 + url: '/api/record/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.videoHistory
  176 + .startTime + '&endTime=' + this.videoHistory.endTime
  177 + }).then(function (res) {
  178 + console.log(JSON.stringify(res));
  179 + }).catch(function (e) {
  180 + // that.videoHistory.searchHistoryResult = falsificationData.recordData;
  181 + });
186 182  
187   - },
188   - playRecord: function(isBackLive, rowData) {
189   - let that = this;
190   - if(isBackLive){
191   - this.videoUrl=this.getVideoUrlBySsrc(this.normalssrc);
192   - return;
193   - }
194   - this.$axios({
195   - method: 'get',
196   - url: '/api/playback/' + this.deviceId + '/' + this.channelId + '?startTime=' + rowData.startTime + '&endTime=' +
197   - rowData.endTime
198   - }).then(function(res) {
199   - let ssrc = res.data.ssrc;
200   - that.videoUrl = that.getVideoUrlBySsrc(ssrc);
201   - //that.videoUrl='http://hls.cntv.kcdnvip.com/asp/hls/main/0303000a/3/default/f466089412c04a759c5515dbfcc3ac3d/main.m3u8?maxbr=2048';
202   - });
  183 + },
  184 + playRecord: function (isBackLive, rowData) {
  185 + let that = this;
  186 + if (isBackLive) {
  187 + this.videoUrl = this.getVideoUrlBySsrc(this.normalssrc);
  188 + return;
  189 + }
  190 + this.$axios({
  191 + method: 'get',
  192 + url: '/api/playback/' + this.deviceId + '/' + this.channelId + '?startTime=' + rowData.startTime + '&endTime=' +
  193 + rowData.endTime
  194 + }).then(function (res) {
  195 + let ssrc = res.data.ssrc;
  196 + that.videoUrl = that.getVideoUrlBySsrc(ssrc);
  197 + //that.videoUrl='http://hls.cntv.kcdnvip.com/asp/hls/main/0303000a/3/default/f466089412c04a759c5515dbfcc3ac3d/main.m3u8?maxbr=2048';
  198 + });
203 199  
204   - },
205   - ptzCamera: function(leftRight, upDown, zoom) {
206   - console.log('云台控制:' + leftRight + ' : ' + upDown + " : " + zoom);
207   - let that = this;
208   - this.$axios({
209   - method: 'post',
210   - url: '/api/ptz/' + this.deviceId + '/' + this.channelId + '?leftRight=' + leftRight + '&upDown=' + upDown +
211   - '&inOut=' + zoom + '&moveSpeed=50&zoomSpeed=50'
212   - }).then(function(res) {});
213   - },
214   - //////////////////////播放器事件处理//////////////////////////
215   - videoError:function(e){
216   - console.log("播放器错误:"+JSON.stringify(e));
217   - }
218   - }
219   - };
  200 + },
  201 + ptzCamera: function (leftRight, upDown, zoom) {
  202 + console.log('云台控制:' + leftRight + ' : ' + upDown + " : " + zoom);
  203 + let that = this;
  204 + this.$axios({
  205 + method: 'post',
  206 + url: '/api/ptz/' + this.deviceId + '/' + this.channelId + '?leftRight=' + leftRight + '&upDown=' + upDown +
  207 + '&inOut=' + zoom + '&moveSpeed=50&zoomSpeed=50'
  208 + }).then(function (res) {});
  209 + },
  210 + //////////////////////播放器事件处理//////////////////////////
  211 + videoError: function (e) {
  212 + console.log("播放器错误:" + JSON.stringify(e));
  213 + }
  214 + }
  215 +};
220 216 </script>
221 217  
222 218 <style>
223   - .control-wrapper {
224   - position: relative;
225   - width: 6.25rem;
226   - height: 6.25rem;
227   - max-width: 6.25rem;
228   - max-height: 6.25rem;
229   - margin: 0 auto;
230   - border-radius: 100%;
231   - float: left;
232   - }
  219 +.control-wrapper {
  220 + position: relative;
  221 + width: 6.25rem;
  222 + height: 6.25rem;
  223 + max-width: 6.25rem;
  224 + max-height: 6.25rem;
  225 + margin: 0 auto;
  226 + border-radius: 100%;
  227 + float: left;
  228 +}
233 229  
234   - .control-btn {
235   - display: flex;
236   - justify-content: center;
237   - position: absolute;
238   - width: 44%;
239   - height: 44%;
240   - border-radius: 5px;
241   - border: 1px solid #78aee4;
242   - box-sizing: border-box;
243   - transition: all 0.3s linear;
244   - }
  230 +.control-btn {
  231 + display: flex;
  232 + justify-content: center;
  233 + position: absolute;
  234 + width: 44%;
  235 + height: 44%;
  236 + border-radius: 5px;
  237 + border: 1px solid #78aee4;
  238 + box-sizing: border-box;
  239 + transition: all 0.3s linear;
  240 +}
245 241  
246   - .control-btn i {
247   - font-size: 20px;
248   - color: #78aee4;
249   - display: flex;
250   - justify-content: center;
251   - align-items: center;
252   - }
  242 +.control-btn i {
  243 + font-size: 20px;
  244 + color: #78aee4;
  245 + display: flex;
  246 + justify-content: center;
  247 + align-items: center;
  248 +}
253 249  
254   - .control-round {
255   - position: absolute;
256   - top: 21%;
257   - left: 21%;
258   - width: 58%;
259   - height: 58%;
260   - background: #fff;
261   - border-radius: 100%;
262   - }
  250 +.control-round {
  251 + position: absolute;
  252 + top: 21%;
  253 + left: 21%;
  254 + width: 58%;
  255 + height: 58%;
  256 + background: #fff;
  257 + border-radius: 100%;
  258 +}
263 259  
264   - .control-round-inner {
265   - position: absolute;
266   - left: 15%;
267   - top: 15%;
268   - display: flex;
269   - justify-content: center;
270   - align-items: center;
271   - width: 70%;
272   - height: 70%;
273   - font-size: 40px;
274   - color: #78aee4;
275   - border: 1px solid #78aee4;
276   - border-radius: 100%;
277   - transition: all 0.3s linear;
278   - }
  260 +.control-round-inner {
  261 + position: absolute;
  262 + left: 15%;
  263 + top: 15%;
  264 + display: flex;
  265 + justify-content: center;
  266 + align-items: center;
  267 + width: 70%;
  268 + height: 70%;
  269 + font-size: 40px;
  270 + color: #78aee4;
  271 + border: 1px solid #78aee4;
  272 + border-radius: 100%;
  273 + transition: all 0.3s linear;
  274 +}
279 275  
280   - .control-inner-btn {
281   - position: absolute;
282   - width: 60%;
283   - height: 60%;
284   - background: #fafafa;
285   - }
  276 +.control-inner-btn {
  277 + position: absolute;
  278 + width: 60%;
  279 + height: 60%;
  280 + background: #fafafa;
  281 +}
286 282  
287   - .control-top {
288   - top: -8%;
289   - left: 27%;
290   - transform: rotate(-45deg);
291   - border-radius: 5px 100% 5px 0;
292   - }
  283 +.control-top {
  284 + top: -8%;
  285 + left: 27%;
  286 + transform: rotate(-45deg);
  287 + border-radius: 5px 100% 5px 0;
  288 +}
293 289  
294   - .control-top i {
295   - transform: rotate(45deg);
296   - border-radius: 5px 100% 5px 0;
297   - }
  290 +.control-top i {
  291 + transform: rotate(45deg);
  292 + border-radius: 5px 100% 5px 0;
  293 +}
298 294  
299   - .control-top .control-inner {
300   - left: -1px;
301   - bottom: 0;
302   - border-top: 1px solid #78aee4;
303   - border-right: 1px solid #78aee4;
304   - border-radius: 0 100% 0 0;
305   - }
  295 +.control-top .control-inner {
  296 + left: -1px;
  297 + bottom: 0;
  298 + border-top: 1px solid #78aee4;
  299 + border-right: 1px solid #78aee4;
  300 + border-radius: 0 100% 0 0;
  301 +}
306 302  
307   - .control-top .fa {
308   - transform: rotate(45deg) translateY(-7px);
309   - }
  303 +.control-top .fa {
  304 + transform: rotate(45deg) translateY(-7px);
  305 +}
310 306  
311   - .control-left {
312   - top: 27%;
313   - left: -8%;
314   - transform: rotate(45deg);
315   - border-radius: 5px 0 5px 100%;
316   - }
  307 +.control-left {
  308 + top: 27%;
  309 + left: -8%;
  310 + transform: rotate(45deg);
  311 + border-radius: 5px 0 5px 100%;
  312 +}
317 313  
318   - .control-left i {
319   - transform: rotate(-45deg);
320   - }
  314 +.control-left i {
  315 + transform: rotate(-45deg);
  316 +}
321 317  
322   - .control-left .control-inner {
323   - right: -1px;
324   - top: -1px;
325   - border-bottom: 1px solid #78aee4;
326   - border-left: 1px solid #78aee4;
327   - border-radius: 0 0 0 100%;
328   - }
  318 +.control-left .control-inner {
  319 + right: -1px;
  320 + top: -1px;
  321 + border-bottom: 1px solid #78aee4;
  322 + border-left: 1px solid #78aee4;
  323 + border-radius: 0 0 0 100%;
  324 +}
329 325  
330   - .control-left .fa {
331   - transform: rotate(-45deg) translateX(-7px);
332   - }
  326 +.control-left .fa {
  327 + transform: rotate(-45deg) translateX(-7px);
  328 +}
333 329  
334   - .control-right {
335   - top: 27%;
336   - right: -8%;
337   - transform: rotate(45deg);
338   - border-radius: 5px 100% 5px 0;
339   - }
  330 +.control-right {
  331 + top: 27%;
  332 + right: -8%;
  333 + transform: rotate(45deg);
  334 + border-radius: 5px 100% 5px 0;
  335 +}
340 336  
341   - .control-right i {
342   - transform: rotate(-45deg);
343   - }
  337 +.control-right i {
  338 + transform: rotate(-45deg);
  339 +}
344 340  
345   - .control-right .control-inner {
346   - left: -1px;
347   - bottom: -1px;
348   - border-top: 1px solid #78aee4;
349   - border-right: 1px solid #78aee4;
350   - border-radius: 0 100% 0 0;
351   - }
  341 +.control-right .control-inner {
  342 + left: -1px;
  343 + bottom: -1px;
  344 + border-top: 1px solid #78aee4;
  345 + border-right: 1px solid #78aee4;
  346 + border-radius: 0 100% 0 0;
  347 +}
352 348  
353   - .control-right .fa {
354   - transform: rotate(-45deg) translateX(7px);
355   - }
  349 +.control-right .fa {
  350 + transform: rotate(-45deg) translateX(7px);
  351 +}
356 352  
357   - .control-bottom {
358   - left: 27%;
359   - bottom: -8%;
360   - transform: rotate(45deg);
361   - border-radius: 0 5px 100% 5px;
362   - }
  353 +.control-bottom {
  354 + left: 27%;
  355 + bottom: -8%;
  356 + transform: rotate(45deg);
  357 + border-radius: 0 5px 100% 5px;
  358 +}
363 359  
364   - .control-bottom i {
365   - transform: rotate(-45deg);
366   - }
  360 +.control-bottom i {
  361 + transform: rotate(-45deg);
  362 +}
367 363  
368   - .control-bottom .control-inner {
369   - top: -1px;
370   - left: -1px;
371   - border-bottom: 1px solid #78aee4;
372   - border-right: 1px solid #78aee4;
373   - border-radius: 0 0 100% 0;
374   - }
  364 +.control-bottom .control-inner {
  365 + top: -1px;
  366 + left: -1px;
  367 + border-bottom: 1px solid #78aee4;
  368 + border-right: 1px solid #78aee4;
  369 + border-radius: 0 0 100% 0;
  370 +}
375 371  
376   - .control-bottom .fa {
377   - transform: rotate(-45deg) translateY(7px);
378   - }
  372 +.control-bottom .fa {
  373 + transform: rotate(-45deg) translateY(7px);
  374 +}
379 375 </style>
... ...