Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
CFFP-HB
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chao Sun
CFFP-HB
Commits
42b8170d
Commit
42b8170d
authored
Aug 24, 2023
by
zeyang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
视频播放统计
parent
7a498a48
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
248 additions
and
47 deletions
+248
-47
myPackageA/videoProject/videoDetail.vue
+246
-45
pages/courseDetail/courseDetail.vue
+2
-2
No files found.
myPackageA/videoProject/videoDetail.vue
View file @
42b8170d
<
template
>
<view
class=
"content"
>
<view
class=
"video"
>
<video
id=
"myVideo"
:src=
"courseInfo.filePathOss"
:poster=
"courseInfo.fileFirstImage"
object-fit=
"contain"
:title=
"courseInfo.fileTitle"
:
initial-time=
"viewTime"
title=
"11"
@
play=
"playVideo"
@
pause=
"pause"
@
timeupdate=
"timeupdate
"
style=
"width: 100vw;height: 500rpx;"
></video>
<video
id=
"myVideo"
:src=
"courseInfo.filePathOss"
:poster=
"courseInfo.fileFirstImage"
object-fit=
"contain"
:
title=
"courseInfo.fileTitle"
style=
"width: 100vw;height: 500rpx;
"
:initial-time=
"viewTime"
@
timeupdate=
"timeupdate"
@
play=
"playVideo"
@
pause=
"pause"
></video>
</view>
<scroll-view
id=
"scrollView"
scroll-y=
"true"
:style=
"
{height:scrollViewHeight+'px'}"
@scrolltolower="scrolltolower">
...
...
@@ -12,13 +12,14 @@
<view>
{{
courseInfo
.
fileTitle
}}
</view>
<view
class=
"iconBottom
"
>
<view
:class=
"isShow?'iconTop':'iconBottom'"
@
click=
"isShow=!isShow
"
>
<text
class=
"iconfont icon-youjiantou"
></text>
</view>
</view>
<view
class=
"videoUser"
>
<view
class=
"videoUserImage"
>
<image
:src=
"lecturerInfo.lecturerUrl"
style=
"height: 70rpx;border-radius: 200rpx;"
mode=
"aspectFit"
></image>
<image
:src=
"lecturerInfo.lecturerUrl"
style=
"height: 70rpx;border-radius: 200rpx;"
mode=
"aspectFit"
></image>
</view>
<view
class=
"videoUserContent"
>
<view
class=
"videoUserName"
>
...
...
@@ -29,13 +30,13 @@
</view>
-->
</view>
</view>
<view
class=
"videoDetail"
>
<view
style=
"color: #414141;"
v-html=
"courseInfo.fileIntroduce"
></view>
<view
class=
"videoDetail"
v-if=
"isShow"
>
<view
v-html=
"courseInfo.fileIntroduce"
></view>
</view>
</view>
<view
style=
"border-top: 1rpx solid #eee;"
>
</view>
<view
class=
"relatedVideoBox"
>
<view
class=
"tagBox"
>
...
...
@@ -44,17 +45,17 @@
</view>
</view>
<view
class=
"relatedVideoList"
>
<view
class=
"relatedVideoItem"
v-for=
"item in
10
"
>
<view
class=
"relatedVideoItem"
v-for=
"item in
relatedCourseList"
@
click=
"play(item)
"
>
<view
style=
"width: 46.5vw;"
>
<image
style=
"height:
25vw;border-radius: 16rpx;"
src=
"../../static/images/irrNavBg.jpg
"
<image
style=
"height:
46.5vw;border-radius: 16rpx;"
:src=
"item.displayImage
"
mode=
"aspectFill"
></image>
</view>
<view
class=
"relatedVideoTitle"
>
这是一个标题················
{{
item
.
fileTitle
}}
</view>
</view>
</view>
<
uni-load-more
iconType=
"circle"
:status=
"moreStatus"
></uni-load-more
>
<
!--
<uni-load-more
iconType=
"circle"
:status=
"moreStatus"
></uni-load-more>
--
>
</view>
</scroll-view>
...
...
@@ -67,28 +68,175 @@
import
api
from
"@/api/api"
;
import
{
cffpURL
}
from
"@/environments/environment"
;
import
common
from
'../../common/common'
;
import
{
onLoad
,
onPageScroll
}
from
"@dcloudio/uni-app"
;
import
{
onLoad
,
onReady
,
onUnload
,
onPageScroll
}
from
"@dcloudio/uni-app"
;
let
windowHeight
=
ref
(
0
);
let
scrollViewHeight
=
ref
(
0
);
//是否展示详细信息
const
isShow
=
ref
(
false
);
// more/loading/noMore
let
moreStatus
=
ref
(
'more'
);
let
userId
=
ref
(
''
);
let
videoId
=
ref
(
''
);
//课程
let
courseInfo
=
ref
({
filePathOss
:
''
,
fileFirstImage
:
''
,
fileTitle
:
''
,
fileIntroduce
:
''
fileTitle
:
''
,
fileIntroduce
:
''
,
packFileId
:
''
});
//讲师
let
lecturerInfo
=
ref
({
lecturerUrl
:
''
,
lecturerName
:
''
,
lecturerIntroduce
:
''
lecturerUrl
:
''
,
lecturerName
:
''
,
lecturerIntroduce
:
''
});
//相关视频
let
relatedCourseList
=
ref
([]);
//视频组件上下文
const
videoContext
=
ref
(
null
);
//播放起始时间
const
viewTime
:
any
=
ref
(
0
);
//视频时长
const
totalTime
:
any
=
ref
(
0
);
//视频是否暂停状态
const
isPauseFlag
=
ref
(
true
);
//新的视频信息
const
newCourseInfo
=
ref
({
fileId
:
''
,
packFileId
:
''
});
//视频播放最新记录
const
videoPlaybackInfo
=
ref
({
id
:
''
,
viewTime
:
''
,
totalTime
:
''
});
//保存记录后返回的Id
const
playbackId
=
ref
(
null
);
//定时器
const
timer
=
ref
(
null
);
const
packFileId
=
ref
(
null
);
// 相关列表点击播放
const
play
=
async
item
=>
{
videoContext
.
value
.
pause
();
if
(
videoId
.
value
!=
item
.
fileId
)
{
// 当点击的课程和当前播放的课程不一致时,执行此方法
uni
.
showLoading
({
title
:
'加载中'
});
uni
.
setStorageSync
(
'cffp_videoId'
,
item
.
fileId
);
newCourseInfo
.
value
=
{
fileId
:
item
.
fileId
,
packFileId
:
item
.
packFileId
,
}
if
(
isPauseFlag
)
{
pause
();
}
}
}
const
saveVideoPlayback
=
()
=>
{
// 视频播放轨迹保存
const
param
=
{
id
:
playbackId
.
value
?
playbackId
.
value
:
null
,
systemType
:
1
,
userId
:
userId
.
value
,
fileId
:
videoId
.
value
,
packFileId
:
courseInfo
.
value
.
packFileId
,
totalTime
:
Math
.
floor
(
totalTime
.
value
),
viewTime
:
Math
.
floor
(
viewTime
.
value
),
playbackStatus
:
viewTime
.
value
>=
totalTime
.
value
?
'2'
:
'1'
}
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
viewTime
.
value
==
0
)
{
resolve
(
'success'
);
return
;
}
api
.
saveVideoPlayback
(
param
).
then
(
res
=>
{
if
(
res
[
'success'
])
{
playbackId
.
value
=
res
[
'data'
][
'id'
];
resolve
(
'success'
);
}
else
{
reject
(
'fail'
)
}
}).
catch
((
err
)
=>
{
reject
(
'fail'
)
})
})
}
const
findVideoPlayback
=
()
=>
{
// 查询视频播放最新记录
const
param
=
{
systemType
:
1
,
userId
:
userId
.
value
,
fileId
:
videoId
.
value
,
packFileId
:
courseInfo
.
value
.
packFileId
,
}
api
.
findVideoPlayback
(
param
).
then
(
res
=>
{
if
(
res
[
'success'
])
{
videoPlaybackInfo
.
value
=
res
[
'data'
];
viewTime
.
value
=
videoPlaybackInfo
.
value
.
viewTime
??
0
;
totalTime
.
value
=
videoPlaybackInfo
.
value
.
totalTime
??
0
;
packFileId
.
value
=
videoPlaybackInfo
.
value
.
id
??
null
;
// this.isRenderVideo = true;
// 跳转到指定位置
videoContext
.
value
.
seek
(
viewTime
.
value
);
uni
.
hideLoading
();
}
else
{
// this.isRenderVideo = true;
totalTime
.
value
=
viewTime
.
value
=
0
;
// 跳转到指定位置
videoContext
.
value
.
seek
(
viewTime
.
value
);
uni
.
hideLoading
();
}
})
};
// 点击播放
const
playVideo
=
(
e
)
=>
{
isPauseFlag
.
value
=
false
;
if
(
viewTime
.
value
>=
totalTime
.
value
)
{
viewTime
.
value
=
0
;
videoContext
.
value
.
seek
(
viewTime
);
}
// 开始/继续播放
if
(
timer
.
value
)
{
clearInterval
(
timer
)
}
timer
.
value
=
setInterval
(()
=>
{
saveVideoPlayback
()
},
20
*
1000
)
}
// 暂停播放
const
pause
=
async
()
=>
{
isPauseFlag
.
value
=
true
;
if
(
timer
.
value
)
{
clearInterval
(
timer
.
value
)
}
const
result
=
await
saveVideoPlayback
();
if
(
result
==
'success'
&&
newCourseInfo
.
value
.
fileId
)
{
videoId
.
value
=
newCourseInfo
.
value
.
fileId
;
courseInfo
.
value
.
packFileId
=
newCourseInfo
.
value
.
packFileId
;
playbackId
.
value
=
null
;
loadCourseDetail
();
}
}
//播放进度改变触发事件
const
timeupdate
=
(
e
)
=>
{
totalTime
.
value
=
e
.
detail
.
duration
;
// 播放进度变化
viewTime
.
value
=
e
.
detail
.
currentTime
>
totalTime
.
value
?
totalTime
.
value
:
e
.
detail
.
currentTime
;
}
//滑动到底事件
const
scrolltolower
=
res
=>
{
...
...
@@ -115,20 +263,13 @@
api
.
courseDetail
({
fileId
:
videoId
.
value
,
userId
:
userId
.
value
,
packFileId
:
courseInfo
.
value
.
packFileId
}).
then
(
res
=>
{
if
(
res
[
'success'
])
{
courseInfo
.
value
=
res
[
'data'
][
'data'
];
lecturerQuery
(
res
[
'data'
][
'data'
][
'fileLecturerId'
]);
// relatedCoursesList();
// if (uni.getStorageSync('h5_coursesharing')) {
// coursesharing = uni.getStorageSync('h5_coursesharing')
// getshareData()
// }
// if (courseInfo.status == 2) {
// findVideoPlayback();
// } else {
// isRenderVideo = true;
// }
loadRelatedCoursesList
();
findVideoPlayback
();
}
})
}
...
...
@@ -148,14 +289,51 @@
}
})
}
// 加载相关视频
const
loadRelatedCoursesList
=
()
=>
{
api
.
relatedCoursesList
({
fileId
:
videoId
.
value
,
userId
:
userId
.
value
,
orderId
:
null
,
packFileId
:
courseInfo
.
value
.
packFileId
,
}).
then
(
res
=>
{
if
(
res
[
'success'
])
{
relatedCourseList
.
value
=
res
[
'data'
][
'data'
][
'relatedCourseList'
];
}
else
{
uni
.
showToast
({
title
:
res
[
'message'
],
duration
:
2000
,
icon
:
'none'
})
}
})
}
onLoad
(
option
=>
{
//视频Id
videoId
.
value
=
option
.
videoId
;
if
(
option
.
videoId
){
uni
.
setStorageSync
(
'cffp_videoId'
,
option
.
videoId
);
videoId
.
value
=
option
.
videoId
;
}
else
{
videoId
.
value
=
uni
.
getStorageSync
(
'cffp_videoId'
);
}
//用户Id
userId
.
value
=
uni
.
getStorageSync
(
'cffp_userId'
);
accessLogSave
();
loadCourseDetail
();
})
onReady
(()
=>
{
videoContext
.
value
=
uni
.
createVideoContext
(
'myVideo'
);
})
onUnload
(()
=>
{
if
(
viewTime
.
value
!=
0
)
{
videoContext
.
value
.
pause
();
saveVideoPlayback
();
if
(
timer
.
value
)
{
clearInterval
(
timer
.
value
)
}
}
})
onMounted
(()
=>
{
//窗口高度
windowHeight
.
value
=
uni
.
getSystemInfoSync
().
windowHeight
;
...
...
@@ -169,41 +347,59 @@
<
style
lang=
"scss"
>
.content
{
color
:
#000
;
.videoDetailBox
{
padding
:
15
rpx
25
rpx
0
rpx
25
rpx
;
padding
:
15
rpx
25
rpx
0
rpx
25
rpx
;
position
:
relative
;
.videoTitleBox
{
font-weight
:
600
;
font-size
:
3
2
rpx
;
font-size
:
3
4
rpx
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
.iconBottom{
transform
:
rotate
(
90deg
)
;
.iconBottom
{
transform
:
rotate
(
90deg
);
}
.iconTop
{
transform
:
rotate
(
-90deg
);
}
}
.videoUser
{
.videoUser
{
display
:
flex
;
align-items
:
center
;
margin
:
20
rpx
0
10
rpx
0
;
.videoUserContent{
margin
:
20
rpx
0
10
rpx
0
;
.videoUserContent
{
//
.videoUserRank{
//
background
:
#5359CD
;
//
border-radius
:
10
rpx
;
//
color
:
#fff
;
//
padding
:
4
rpx
20
rpx
;
//
}
.videoUserName
{
.videoUserName
{
padding-bottom
:
20
rpx
;
font-size
:
32
rpx
;
}
}
.videoUserImage
{
width
:
70
rpx
;
.videoUserImage
{
width
:
70
rpx
;
margin-right
:
15
rpx
;
}
}
.videoDetail
{
color
:
#414141
;
font-size
:
30
rpx
;
padding-bottom
:
20
rpx
;
overflow
:
hidden
;
}
}
.relatedVideoBox
{
...
...
@@ -229,8 +425,13 @@
width
:
46.5vw
;
.relatedVideoTitle
{
font-size
:
30
rpx
;
font-size
:
28
rpx
;
display
:
-webkit-box
;
-webkit-line-clamp
:
2
;
-webkit-box-orient
:
vertical
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
height
:
79
rpx
;
}
}
}
...
...
pages/courseDetail/courseDetail.vue
View file @
42b8170d
...
...
@@ -558,7 +558,7 @@
this
.
isRenderVideo
=
true
;
this
.
totalTime
=
this
.
viewTime
=
0
;
// 跳转到指定位置
this
.
videoContext
.
seek
(
thi
e
.
viewTime
);
this
.
videoContext
.
seek
(
thi
s
.
viewTime
);
uni
.
hideLoading
();
}
})
...
...
@@ -618,7 +618,7 @@
}
}
},
timeupdate
(
e
)
{
timeupdate
(
e
)
{
this
.
totalTime
=
e
.
detail
.
duration
;
// 播放进度变化
this
.
viewTime
=
e
.
detail
.
currentTime
>
this
.
totalTime
?
this
.
totalTime
:
e
.
detail
.
currentTime
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment