#65991 Тормоза и ошибки на WebOS
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
{
|
||||
# email для уведомлений Let's Encrypt
|
||||
email am@just-work.org
|
||||
}
|
||||
|
||||
# Хост и прокси
|
||||
mule.jwrk.org {
|
||||
reverse_proxy server:8080
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
aoc_app.zip__DEL__Xi+Vnza2bfBYCpTzhMX8HO7sSyo5JfBi17aPIXWLhlgawq3P3ec6FxooSW51jvGyPKSVHAVFXNrp
|
||||
NXzDtaWCXw==
|
||||
config.xml__DEL__nsWBkoKSk7r0pu0ubb37gDanmRdIYcujiTiy0EErZP7ExRQajQE00K+sneKa8eSSOxH0OOecX9Ip
|
||||
X++l2ykBJA==
|
||||
config.xml__DEL__PRuz95KE2QodgYrVJWPvkcWMK+Y6ykfDlRjDrXdQw2vlrXdd/T/W++TTRz1pJ0LTem6M0LjxTrSS
|
||||
20iJYH+sLA==
|
||||
css/style.css__DEL__/QJ+/nq2xebaAiLLB7s3kvL1fT/61LBickart4MZi3T2I1+AyTrBYD61Nk91tjKcvcN6RGiA5O63
|
||||
5o7u57rIRQ==
|
||||
icon.png__DEL__BTGBG483ma/3HgWnreWF2xbdzr4F0gTRWjwxoSV+7kKBWt4UJTuv5WE4DhKdU4in2kwn/55O/qPD
|
||||
@@ -12,5 +12,5 @@ index.html__DEL__CYjkR+ZNwp7L/if9LsT+uFjGHChwaswBoSaFu+BgC+SlB3r0YGND4cN20rlg1At
|
||||
oDBqLNXYGw==
|
||||
js/main.js__DEL__Gfmwxx8WB6EHvN7d/Hs+7I1Blt+5u6JI6J+BljCGddvh7brF4mywWKg8iTnDvdA8Xb35l+178i0D
|
||||
hwV/qPVCxw==
|
||||
author-signature.xml__DEL__M/eFnHFi2g/GYv0/D2hsHUZDLs9J1DZjCANuMtBFImSPGBr8F6JadxBVou43O8wyeEacadF9ZDG9
|
||||
5prLXzM+gg==
|
||||
author-signature.xml__DEL__d49WGJ3MjEY0kD9IHGog/wEPNo2zS1s5pHer6i1FM2dZalIHsRuRsAVGlVxlXM5pFSCkp9kxWf5L
|
||||
1J59A2Tfgw==
|
||||
|
||||
@@ -9,8 +9,8 @@ NXzDtaWCXw==</DigestValue>
|
||||
</Reference>
|
||||
<Reference URI="config.xml">
|
||||
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"></DigestMethod>
|
||||
<DigestValue>nsWBkoKSk7r0pu0ubb37gDanmRdIYcujiTiy0EErZP7ExRQajQE00K+sneKa8eSSOxH0OOecX9Ip
|
||||
X++l2ykBJA==</DigestValue>
|
||||
<DigestValue>PRuz95KE2QodgYrVJWPvkcWMK+Y6ykfDlRjDrXdQw2vlrXdd/T/W++TTRz1pJ0LTem6M0LjxTrSS
|
||||
20iJYH+sLA==</DigestValue>
|
||||
</Reference>
|
||||
<Reference URI="css%2Fstyle.css">
|
||||
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"></DigestMethod>
|
||||
@@ -47,49 +47,42 @@ QY10fG1EWQ==</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>
|
||||
FSRsPfbPzOeJ6kYa8qwARh3fRZyttY2IZAUTNEcC+Jx6LuZxu8kZkK059HyxSfBAdPTq7r3dECv+
|
||||
Jxay4KsWTXUHSFxQLgpMkFhI4wfTiN8h6hYwHqhn9sxpUnnk8YDkUVULCgMPcjq4jUeV6K/+eDwy
|
||||
BshnFQQIYiYfVPUX/tXBDevovg/x+q3j9TX/7W24Fpkq9vw/ti+nbyk7KF8Uvt6cgLA2qqoslrAr
|
||||
6YOymNO40uvBoKkpcMgdoRdXgkRrQZo9vDjbhfxZua2Yc+74lTXSmXVaVYmiAFGhWGUu0AJpZB+V
|
||||
nbDbicP65tQwJEAKeUTBiIm7A9SGjxX6B+5Vvw==
|
||||
KF5KNSA49WfpUYrUi3vmhB3JnTjqXObPGju0bzEWw3ztUJKO/uk9JG+yRbzSW+476lnPBzMGBbRo
|
||||
e+q+r39TvmCAQkhL1h/1KpZbpgjvRtY6ZWspOkFXzEVjXiRtZPhGy4IJl8DgxQqDwSToyZYkKgPZ
|
||||
5HUu17mxR2xIGA9DgeM=
|
||||
</SignatureValue>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>
|
||||
MIIDaTCCAlGgAwIBAgIBAjANBgkqhkiG9w0BAQ0FADCBijELMAkGA1UEBhMCS1IxFDASBgNVBAgT
|
||||
C1NvdXRoIEtvcmVhMQ4wDAYDVQQHEwVTdXdvbjEmMCQGA1UEChMdU2Ftc3VuZyBFbGVjdHJvbmlj
|
||||
cyBDby4sIEx0ZC4xCzAJBgNVBAsTAlZEMSAwHgYDVQQDExdTYW1zdW5nIEF1dGhvciBDQSBDbGFz
|
||||
czAeFw0yNTA3MDMxNTE3MDNaFw0yNjA3MDMxNTE3MDNaMEkxCTAHBgNVBAYTADEJMAcGA1UECBMA
|
||||
MQkwBwYDVQQHEwAxCTAHBgNVBAoTADEJMAcGA1UECxMAMRAwDgYDVQQDEwd0di1jZXJ0MIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjOugberkYHutm3WeIqlkcB56Juyf0D7tOOztFSWE
|
||||
t0CP7i5RYzOXGDQ8ZtmCXQHYBxQB+1eNmpAwEHOkrw5R3qqBdDuBw3Hud1qJJgknrgNJHsUF1pg9
|
||||
LxkLsvRsu6cQSIoeCh9k1LU4ytquY4ZDKn+1IABxWipMp995CoqK8kOzgLQ6Mhva8BksE7vA+t+3
|
||||
KH6/d8wVSwA1vMbcnbsC+J81BrSfpHWtn38XSGPZw6D6ZKL/RHOIu6/20Ft+OXCLtu2G0M9Wg7MK
|
||||
AQsB3AMRn81EF4cCEENkuw/KiNkiZCMJHXaJvbs0NKBx/tDV+PAtKcbnXGBJF4zCl/XbPIkzfwID
|
||||
AQABoxowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQ0FAAOCAQEAO2yLTZ8O
|
||||
Am0ad/zReLaK+b5L1438FRjYR5TVRAv/QVF7Kad1oFMDJRc9sCB6JwHyjxgTkyJInaYVojhQwazP
|
||||
D7b6bj2EryUHBWCExjTFaoQ7hxZEu01E4kHtnK1OOqICgCbI3GLtH2CJXTG8QQljqKzWUIritP3o
|
||||
Llp7ccuVZ2m4bWiRe8sKNfr/QJ9mAQU5BnRspcnltSTa4WhapJ/+WKc5tk7i3tl9BkMRweMA9qn/
|
||||
hOeC41f8mGweeiVLxZqxNOPcgCxEQWm50x9IFo8Dxpab0m3W1u8CyHwDteVJjjhQXg2tIgzj6S3u
|
||||
ev9IuF52clygqML7oLvSKq0KC0eNUA==
|
||||
MIIClTCCAX2gAwIBAgIGAZhmXwGaMA0GCSqGSIb3DQEBDQUAMFYxGjAYBgNVBAoMEVRpemVuIEFz
|
||||
c29jaWF0aW9uMRowGAYDVQQLDBFUaXplbiBBc3NvY2lhdGlvbjEcMBoGA1UEAwwTVGl6ZW4gRGV2
|
||||
ZWxvcGVycyBDQTAeFw0yNTA4MDExNjAyMzlaFw0yNzAxMDEwMDAwMDBaMBExDzANBgNVBAMMBmVy
|
||||
dDEyMzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAiwW+5wQuJiS2rNeF+b3yM5eF/GsrsJs+
|
||||
iXgXdvtvU0XVEumjQsBvwqcnskHo3Wk1GgnsJx9YRdjG4MqP1JtwoSDZE6Ly8ENplH5NvJmsoTgM
|
||||
i8Fx0NW7nT2NqdpKgF8ymcgxeiHPQNgPimh4gsXakga9NJhuGh1ZsJpcZcvZuyUCAwEAAaMyMDAw
|
||||
DAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcN
|
||||
AQENBQADggEBAIH8WSGEJjLWGaVE64sQRwJ5JSc56yXWBJeLMyECOZ6hXPC/vA3xtswT3MBI3gj5
|
||||
65h77/0QjBaDGWzI5PKEdYwRN7XQhQl5QvaFbv1HfqqciBwB8rpBaQu4YZNvWzMBvu1Yw9jiJOmP
|
||||
Dr6hDRa/pGbd7dNUt+hr0PqubhJY43eD05PbVsUFpI3PJnQutg7bB1tj2zpUrQBHtZSozEZgSywW
|
||||
Zatw8RB8uKxf/Z5cLCXK70liCwQ9kT7foYSeUGxl9sI2m1abmEVCGAVl0VT9Or+DwW1uGJEiGjIg
|
||||
o/Wv4PfxEgpGUsn7dB6nHXbXPALwKRa68VFno06t0gabQWfdjlI=
|
||||
</X509Certificate>
|
||||
<X509Certificate>
|
||||
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
|
||||
</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
|
||||
@@ -9,13 +9,13 @@ NXzDtaWCXw==</DigestValue>
|
||||
</Reference>
|
||||
<Reference URI="author-signature.xml">
|
||||
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"></DigestMethod>
|
||||
<DigestValue>M/eFnHFi2g/GYv0/D2hsHUZDLs9J1DZjCANuMtBFImSPGBr8F6JadxBVou43O8wyeEacadF9ZDG9
|
||||
5prLXzM+gg==</DigestValue>
|
||||
<DigestValue>d49WGJ3MjEY0kD9IHGog/wEPNo2zS1s5pHer6i1FM2dZalIHsRuRsAVGlVxlXM5pFSCkp9kxWf5L
|
||||
1J59A2Tfgw==</DigestValue>
|
||||
</Reference>
|
||||
<Reference URI="config.xml">
|
||||
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"></DigestMethod>
|
||||
<DigestValue>nsWBkoKSk7r0pu0ubb37gDanmRdIYcujiTiy0EErZP7ExRQajQE00K+sneKa8eSSOxH0OOecX9Ip
|
||||
X++l2ykBJA==</DigestValue>
|
||||
<DigestValue>PRuz95KE2QodgYrVJWPvkcWMK+Y6ykfDlRjDrXdQw2vlrXdd/T/W++TTRz1pJ0LTem6M0LjxTrSS
|
||||
20iJYH+sLA==</DigestValue>
|
||||
</Reference>
|
||||
<Reference URI="css%2Fstyle.css">
|
||||
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"></DigestMethod>
|
||||
@@ -52,52 +52,40 @@ GyvKX9Snig==</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>
|
||||
h/6uo1RBmf2PcDwFShF1rJktgYolWJ+6oAfNxWnQaOAR4aITvD5BLGIXwA9JHLQXTtByBP2q8ODd
|
||||
QUBGPXZLz67cHdzuWVHNgcb8FSuiHZzYXsCRKmgwj5BN24PHe41bZ/TSQejJTsPgTZ5R3jiOMTzP
|
||||
gY67phZ7QCWj515gYvvWA4Y7Y888HbJpGFx8oStRRPl0hTLkr4dcOOMpX5XTABI2KTqNWDReiTUy
|
||||
ulOE6MsdrtHEip6BynRvSgQJOGf9+iWjFm65LlHGt4G9WcVErPfhVNxXjgcxspL9ovo+vCZDSOP8
|
||||
E0f5jOAM6pxBSIilM1tUg4jlcywzoNe2pSj4KQ==
|
||||
YiUEi2AHQ7GtltquG6Y6TdXKQA/CtYYWtYnsO1CEpbq5oX0gQRN6RI2jrNoktuHyzZkL+jZOs7wL
|
||||
dghXMoY89v4PSce418R+sQ0VHmgSfMGVdJm9vE9pKXyb6upCi+5dfNRrcUSqY7u5U6YZmcczJmnR
|
||||
lStlx/B4VIzVSDs3vhE=
|
||||
</SignatureValue>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>
|
||||
MIID4zCCAsugAwIBAgIBZDANBgkqhkiG9w0BAQ0FADCBjzELMAkGA1UEBhMCS1IxFDASBgNVBAgM
|
||||
C1NvdXRoIEtvcmVhMQ4wDAYDVQQHDAVTdXdvbjEmMCQGA1UECgwdU2Ftc3VuZyBFbGVjdHJvbmlj
|
||||
cyBDby4sIEx0ZC4xCzAJBgNVBAsMAlZEMSUwIwYDVQQDDBxWRCBERVZFTE9QRVIgUHVibGljIENB
|
||||
IENsYXNzMB4XDTI1MDcwMzE1MzExNFoXDTI2MDcwMzE1MzExNFowcTERMA8GA1UEAwwIVGl6ZW5T
|
||||
REsxCTAHBgNVBAsMADEJMAcGA1UECgwAMQkwBwYDVQQHDAAxCTAHBgNVBAgMADEJMAcGA1UEBhMA
|
||||
MSUwIwYJKoZIhvcNAQkBFhZqc2phcmRpbmVpcm9AZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAwxqNIiL0PS/WtelG8kXZf0pehwiIodi+QOdNedi32clrSHYoGJr8yaDA
|
||||
pqx9g2LRWDJM1Av9iBNz89n4GZX3HUqPSbdKmV/k0jO7OoHOXPVDbus7uIlbG/9y4kZtXx/OTKSa
|
||||
XX5nThSbknwP/qQcsA+H/MSuj0zgE+40scLd72kH3NU0xAg40tdB6J7EemodOkxxQPAWXD42nNAu
|
||||
KLn25sALITwpuQDBXrqPcF3496jXMStGKHYxCpObkv+4rSd8P0s5hVhX5+j1Xr8FfjCgabGK575a
|
||||
zIzc+orZIBvDbLut6kyLWhbbzeog0YIuh53f3+YlPE1KAPm4X2nWpBxLFwIDAQABo2cwZTBjBgNV
|
||||
HREEXDBahhRVUk46dGl6ZW46cGFja2FnZWlkPYYgVVJOOnRpemVuOmRldmljZWlkPVhUQ2pZalpY
|
||||
WkJaVkuGIFVSTjp0aXplbjpkZXZpY2VpZD1YVENKWUpaWFpCWlZLMA0GCSqGSIb3DQEBDQUAA4IB
|
||||
AQAJ13iGnABSVF0carYNY6DjVaazKfMpg9B30CqHz8+2IpYLhaZuN4sW5cYpA5cIb6gjbRdyCGrc
|
||||
ly5YSkhd61pjeV/Lclw9+Sp0YQQ6RkYSJqLQKrRKwo3XluEGe2Yhrj3uliDAESzdtf0fVqWx+NHI
|
||||
5lSsFwS1wILJ6ovPYllWzC1VYrukf6z+yZLaFdBHYAygFRzNrQjDVnsO7kGW264uULN/csop3TcO
|
||||
xcPb3yi7dWbZjgKpZnNurpx8C3UEtQ4CbPL6HtvDemeEP94qDLLsUyZHwt4QaxJae8Yygs6o3L6j
|
||||
ja2S8auhtN2yclvvIl1/hblxvX4+vmwNQ2bc9p6E
|
||||
MIICmzCCAgQCCQDXI7WLdVZwiTANBgkqhkiG9w0BAQUFADCBjzELMAkGA1UEBhMCS1IxDjAMBgNV
|
||||
BAgMBVN1d29uMQ4wDAYDVQQHDAVTdXdvbjEWMBQGA1UECgwNVGl6ZW4gVGVzdCBDQTEiMCAGA1UE
|
||||
CwwZVGl6ZW4gRGlzdHJpYnV0b3IgVGVzdCBDQTEkMCIGA1UEAwwbVGl6ZW4gUHVibGljIERpc3Ry
|
||||
aWJ1dG9yIENBMB4XDTEyMTAyOTEzMDMwNFoXDTIyMTAyNzEzMDMwNFowgZMxCzAJBgNVBAYTAktS
|
||||
MQ4wDAYDVQQIDAVTdXdvbjEOMAwGA1UEBwwFU3V3b24xFjAUBgNVBAoMDVRpemVuIFRlc3QgQ0Ex
|
||||
IjAgBgNVBAsMGVRpemVuIERpc3RyaWJ1dG9yIFRlc3QgQ0ExKDAmBgNVBAMMH1RpemVuIFB1Ymxp
|
||||
YyBEaXN0cmlidXRvciBTaWduZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALtMvlc5hENK
|
||||
90ZdA+y66+Sy0enD1gpZDBh5T9RP0oRsptJv5jjNTseQbQi0SZOdOXb6J7iQdlBCtR343RpIEz8H
|
||||
mrBy7mSY7mgwoU4EPpp4CTSUeAuKcmvrNOngTp5Hv7Ngf02TTHOLK3hZLpGayaDviyNZB5PdqQdB
|
||||
hokKjzAzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAvGp1gxxAIlFfhJH1efjb9BJK/rtRkbYn9+Ez
|
||||
GEbEULg1svsgnyWisFimI3uFvgI/swzr1eKVY3Sc8MQ3+Fdy3EkbDZ2+WAubhcEkorTWjzWz2fL1
|
||||
vKaYjeIsuEX6TVRUugHWudPzcEuQRLQf8ibZWjbQdBmpeQYBMg5x+xKLCJc=
|
||||
</X509Certificate>
|
||||
<X509Certificate>
|
||||
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
|
||||
VhfnkHwPltmrpYVe
|
||||
</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
<widget xmlns:tizen="http://tizen.org/ns/widgets" xmlns="http://www.w3.org/ns/widgets" id="http://yourdomain/BasicUI" version="1.0.0" viewmodes="maximized">
|
||||
<access origin="http://188.246.226.196:8080" subdomains="false"></access>
|
||||
<access origin="*" subdomains="false"></access>
|
||||
<tizen:application id="ckiRCUgzke.BasicUI" package="ckiRCUgzke" required_version="8.0"/>
|
||||
<tizen:application id="ckiRCUgzke.BasicUI" package="ckiRCUgzke" required_version="5.0"/>
|
||||
<content src="index.html"/>
|
||||
<icon src="icon.png"/>
|
||||
<name>BasicUI</name>
|
||||
<tizen:privilege name="http://tizen.org/privilege/download"/>
|
||||
<tizen:privilege name="http://tizen.org/privilege/mediacontroller.client"/>
|
||||
<tizen:privilege name="http://tizen.org/privilege/volume.set"/>
|
||||
<tizen:privilege name="http://developer.samsung.com/privilege/drminfo"/>
|
||||
<tizen:privilege name="http://developer.samsung.com/privilege/drmplay"/>
|
||||
<tizen:privilege name="http://developer.samsung.com/privilege/network.public"/>
|
||||
<tizen:privilege name="http://tizen.org/privilege/tv.inputdevice"/>
|
||||
<tizen:privilege name="http://tizen.org/privilege/application.launch"/>
|
||||
<tizen:profile name="tv-samsung"/>
|
||||
<tizen:setting screen-orientation="portrait" context-menu="enable" background-support="disable" encryption="disable" install-location="auto" hwkey-event="enable"/>
|
||||
</widget>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html style="width: 100vw; height: 100vh; margin: 0; padding: 0; background: #000; overflow: hidden;">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
@@ -8,22 +8,28 @@
|
||||
<title>Tizen Mobile Web Basic Application</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css" />
|
||||
<script type="text/javascript" src="$WEBAPIS/webapis/webapis.js"></script>
|
||||
<script language="JavaScript" src="http://188.246.226.196:8080/distribution/vokaPlayer.global.js"></script>
|
||||
<script language="JavaScript" src="https://mule.jwrk.org/distribution/vokaPlayer.global.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main" class="page">
|
||||
<div class="contents">
|
||||
<span id="content-text">Basic</span>
|
||||
<div id="my-video"/>
|
||||
</div>
|
||||
</div>
|
||||
<body style="width: 100vw; height: 100vh; margin: 0; padding: 0; background: #000; overflow: hidden;">
|
||||
<div id="my-video"></div>
|
||||
</body>
|
||||
|
||||
<script language="JavaScript">
|
||||
console.log(webapis)
|
||||
console.log(webapis.avplay)
|
||||
window.addEventListener('load', () => {
|
||||
tizen.tvinputdevice.registerKey('MediaPlayPause');
|
||||
tizen.tvinputdevice.registerKey('MediaRewind');
|
||||
tizen.tvinputdevice.registerKey('MediaFastForward');
|
||||
tizen.tvinputdevice.registerKey('MediaPlay');
|
||||
tizen.tvinputdevice.registerKey('MediaPause');
|
||||
tizen.tvinputdevice.registerKey('MediaStop');
|
||||
tizen.tvinputdevice.registerKey('MediaTrackPrevious');
|
||||
tizen.tvinputdevice.registerKey('MediaTrackNext');
|
||||
tizen.tvinputdevice.registerKey('ArrowRight');
|
||||
tizen.tvinputdevice.registerKey('ArrowLeft');
|
||||
});
|
||||
|
||||
var player = spbtvplayer('my-video', {
|
||||
log: true,
|
||||
features: {
|
||||
api: true,
|
||||
drm: false,
|
||||
@@ -36,7 +42,7 @@
|
||||
movieId: null,
|
||||
episodeId: null,
|
||||
newsId: null,
|
||||
apiHost: 'http://188.246.226.196:8080/',
|
||||
apiHost: 'https://mule.jwrk.org',
|
||||
},
|
||||
uiConfig: {
|
||||
initAsLive: true
|
||||
@@ -62,7 +68,7 @@
|
||||
},
|
||||
});
|
||||
player.afterInitialize(() => {
|
||||
console.log("Inited 1")
|
||||
console.log("Initialized")
|
||||
})
|
||||
|
||||
player.addEventListener('play', onPlay, window)
|
||||
@@ -81,7 +87,6 @@
|
||||
|
||||
function oncontrolsHide() { console.log("on oncontrolsHide") }
|
||||
|
||||
//
|
||||
function controlBarHide() {
|
||||
player.setControlbarVisibility(false)
|
||||
}
|
||||
@@ -104,11 +109,6 @@
|
||||
}
|
||||
|
||||
</script>
|
||||
<button onclick="controlBarShow()" type="button">SHOW CONTROL BAR</button>
|
||||
<button onclick="controlBarHide()" type="button">HIDE CONTROL BAR</button>
|
||||
<button onclick="changeQualityAuto()" type="button">AUTO QUALITY</button>
|
||||
<button onclick="changeQualityLowest()" type="button">LOWEST QUALITY</button>
|
||||
<button onclick="changeQualityBest()" type="button">BEST QUALITY</button>
|
||||
|
||||
<script>
|
||||
/*
|
||||
@@ -119,8 +119,6 @@ if (webapis.avplay) {
|
||||
webapis.avplay.play();
|
||||
}
|
||||
*/
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</html>
|
||||
|
||||
Executable
+73
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tizen AVPlay Minimal (Official Object)</title>
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0; padding: 0;
|
||||
width: 100vw; height: 100vh;
|
||||
background: #000;
|
||||
overflow: hidden;
|
||||
}
|
||||
#av-object {
|
||||
position: absolute;
|
||||
left: 60px;
|
||||
top: 60px;
|
||||
width: 800px;
|
||||
height: 450px;
|
||||
border: 6px solid lime;
|
||||
z-index: 1000;
|
||||
background: #111;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="my-video">
|
||||
<object id="av-object" type="application/avplayer"></object>
|
||||
</div>
|
||||
<script>
|
||||
function run () {
|
||||
// Координаты object элемента
|
||||
var obj = document.getElementById('av-object');
|
||||
var rect = obj.getBoundingClientRect();
|
||||
console.log("setDisplayRect:", rect.left, rect.top, rect.width, rect.height);
|
||||
|
||||
// Официальный тестовый поток
|
||||
var url = "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3/gear1/prog_index.m3u8";
|
||||
|
||||
webapis.avplay.open(url);
|
||||
webapis.avplay.setListener({
|
||||
onbufferingstart: function() {
|
||||
console.log("AVPlay: buffering start");
|
||||
},
|
||||
onbufferingprogress: function(percent) {
|
||||
console.log("AVPlay: buffering progress", percent);
|
||||
},
|
||||
onbufferingcomplete: function() {
|
||||
console.log("AVPlay: buffering complete");
|
||||
// Важно! setDisplayRect по координатам object-а
|
||||
webapis.avplay.setDisplayRect(
|
||||
Math.round(rect.left),
|
||||
Math.round(rect.top),
|
||||
Math.round(rect.width),
|
||||
Math.round(rect.height)
|
||||
);
|
||||
webapis.avplay.play();
|
||||
},
|
||||
onrenderingstart: function () {
|
||||
console.log("AVPlay: video rendering started!");
|
||||
},
|
||||
oncurrentplaytime: function (t) {
|
||||
// console.log("Current time:", t);
|
||||
},
|
||||
onerror: function (err) {
|
||||
console.error("AVPlay error:", err);
|
||||
}
|
||||
});
|
||||
webapis.avplay.prepareAsync();
|
||||
};
|
||||
run();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
8e961301-1a56-4a69-ad97-a82e65bd4a3e
|
||||
@@ -1,9 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head> </head>
|
||||
<head>
|
||||
<script type="text/javascript" src="webOSTV.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.location.href = "http://localhost:8080/?apiHost=localhost:8080";
|
||||
window.location.href = "https://mule.jwrk.org/index.html?apiHost=https://mule.jwrk.org";
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,181 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" style="width: 100%; height: 100%">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
|
||||
<script language="JavaScript" src="./distribution/vokaPlayer.global.js"></script>
|
||||
</head>
|
||||
<body style="width: 100%; height: 100%">
|
||||
<h1>Hello world</h1>
|
||||
<div id="my-video" style="width: 100%; height: 100%"></div>
|
||||
<button onclick="controlBarShow()" type="button">SHOW CONTROL BAR</button>
|
||||
<button onclick="controlBarHide()" type="button">HIDE CONTROL BAR</button>
|
||||
<button onclick="changeQualityAuto()" type="button">AUTO QUALITY</button>
|
||||
<button onclick="changeQualityLowest()" type="button">LOWEST QUALITY</button>
|
||||
<button onclick="changeQualityBest()" type="button">BEST QUALITY</button>
|
||||
<button onclick="setEngAudioTrack()" type="button">ENGLISH AUDIO</button>
|
||||
<button onclick="setDubAudioTrack()" type="button">DUBBING AUDIO</button>
|
||||
<button onclick="disableSubs()" type="button">DISABLE SUBS</button>
|
||||
<button onclick="setDeSubs()" type="button">DEUTCH SUBS</button>
|
||||
<button onclick="setEnSubs()" type="button">ENGLISH SUBS</button>
|
||||
<h2>Logs</h2>
|
||||
<div id="logs" class="logs"></div>
|
||||
<script language="JavaScript">
|
||||
var player = spbtvplayer('my-video', {
|
||||
log: true,
|
||||
features: {
|
||||
api: true,
|
||||
drm: false,
|
||||
metrics: true
|
||||
},
|
||||
apiConfig: {
|
||||
channelId: 'dash-playready-vod',
|
||||
urlGetParams: 'minheight=400',
|
||||
clientId: null,
|
||||
movieId: null,
|
||||
episodeId: null,
|
||||
newsId: null,
|
||||
},
|
||||
uiConfig: {
|
||||
initAsLive: true
|
||||
},
|
||||
globalOpts: {
|
||||
uiLanguage: 'ru'
|
||||
},
|
||||
streamOpts: {
|
||||
autoplay: true
|
||||
},
|
||||
controls: {
|
||||
externalSubtitles: {
|
||||
url: "https://raw.githubusercontent.com/videojs/video.js/c7298d40a4632a6e9dfcd5a2f5cc3bbe92a78744/docs/examples/elephantsdream/captions.ru.vtt",
|
||||
lang: 'ru'
|
||||
},
|
||||
zoomButton: {
|
||||
isVisible: true,
|
||||
enable: true,
|
||||
},
|
||||
editing: {
|
||||
enable: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
player.afterInitialize(() => {
|
||||
console.log("afterInitialize")
|
||||
player.setControlbarVisibility(false)
|
||||
})
|
||||
|
||||
player.addEventListener('play', onPlay, window)
|
||||
player.addEventListener('pause', onPause, window)
|
||||
player.addEventListener('canplay', onCanPlay, window)
|
||||
player.addEventListener('controlbarShow', onControlsShow, window)
|
||||
player.addEventListener('controlbarHide', oncontrolsHide, window)
|
||||
|
||||
function onPlay() { console.log("on PLAY") }
|
||||
|
||||
function onPause() { console.log("on PAUSE") }
|
||||
|
||||
function onCanPlay() { console.log("on CANPLAY") }
|
||||
|
||||
function onControlsShow() { console.log("on onControlsShow") }
|
||||
|
||||
function oncontrolsHide() { console.log("on oncontrolsHide") }
|
||||
|
||||
//
|
||||
function controlBarHide() {
|
||||
player.setControlbarVisibility(false)
|
||||
}
|
||||
|
||||
function controlBarShow() {
|
||||
player.setControlbarVisibility(true)
|
||||
}
|
||||
|
||||
function changeQualityAuto() {
|
||||
player.setSelectedVideoQuality(-1)
|
||||
}
|
||||
|
||||
function changeQualityLowest() {
|
||||
player.setSelectedVideoQuality(0)
|
||||
}
|
||||
|
||||
function changeQualityBest() {
|
||||
var quality = player.getVideoQualityList()
|
||||
player.setSelectedVideoQuality(quality.length - 1)
|
||||
}
|
||||
|
||||
function setDubAudioTrack() {
|
||||
player.setCurrentAudioTrack(1)
|
||||
}
|
||||
|
||||
function setEngAudioTrack() {
|
||||
player.setCurrentAudioTrack(0)
|
||||
}
|
||||
|
||||
function disableSubs() {
|
||||
player.setCurrentSubtitlesTrack(-1)
|
||||
}
|
||||
|
||||
function setDeSubs() {
|
||||
player.setCurrentSubtitlesTrack(0)
|
||||
}
|
||||
|
||||
function setEnSubs() {
|
||||
player.setCurrentSubtitlesTrack(1)
|
||||
}
|
||||
|
||||
const fireEvents = [
|
||||
'play',
|
||||
'pause',
|
||||
'canplay',
|
||||
'ended',
|
||||
// 'timeupdate',
|
||||
'error',
|
||||
'volumechange',
|
||||
'controlbarShow',
|
||||
'controlbarHide',
|
||||
'qualityChange',
|
||||
'sourceAttached',
|
||||
'zoomButtonChange',
|
||||
'trackChange',
|
||||
'bufferLengthUpdate',
|
||||
'zoomModeChange',
|
||||
'toolboxStartSel',
|
||||
'toolboxEndSel',
|
||||
'toolboxProcessSel',
|
||||
'destroyed',
|
||||
'bufferingUpdate',
|
||||
'timeshiftUpdate',
|
||||
]
|
||||
|
||||
function currentTime() {
|
||||
const d = new Date()
|
||||
const h = `${d.getHours()}`.padStart(2, '0')
|
||||
const m = `${d.getMinutes()}`.padStart(2, '0')
|
||||
const s = `${d.getSeconds()}`.padStart(2, '0')
|
||||
return h + ":" + m + ":" + s
|
||||
}
|
||||
|
||||
function addLog (message) {
|
||||
const element = document.createElement('div')
|
||||
element.classList.add('log-item')
|
||||
element.innerHTML = '<b class="current-time">' + currentTime() + '</b> ' + message;
|
||||
document.querySelector("#logs").prepend(element)
|
||||
}
|
||||
|
||||
fireEvents.forEach(event => {
|
||||
player.addEventListener(event, (payload) => {
|
||||
addLog (`<i>${event}</i> : ${JSON.stringify(payload)}`)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
.logs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 600px;
|
||||
border: 1px solid gray;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,182 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" style="width: 100%; height: 100%">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
|
||||
<script language="JavaScript" src="./distribution/vokaPlayer.global.js"></script>
|
||||
</head>
|
||||
<body style="width: 100%; height: 100%">
|
||||
<h1>Hello world</h1>
|
||||
<div id="my-video" style="width: 100%; height: 100%"></div>
|
||||
<button onclick="controlBarShow()" type="button">SHOW CONTROL BAR</button>
|
||||
<button onclick="controlBarHide()" type="button">HIDE CONTROL BAR</button>
|
||||
<button onclick="changeQualityAuto()" type="button">AUTO QUALITY</button>
|
||||
<button onclick="changeQualityLowest()" type="button">LOWEST QUALITY</button>
|
||||
<button onclick="changeQualityBest()" type="button">BEST QUALITY</button>
|
||||
<button onclick="setEngAudioTrack()" type="button">ENGLISH AUDIO</button>
|
||||
<button onclick="setDubAudioTrack()" type="button">DUBBING AUDIO</button>
|
||||
<button onclick="disableSubs()" type="button">DISABLE SUBS</button>
|
||||
<button onclick="setDeSubs()" type="button">DEUTCH SUBS</button>
|
||||
<button onclick="setEnSubs()" type="button">ENGLISH SUBS</button>
|
||||
<h2>Logs</h2>
|
||||
<div id="logs" class="logs"></div>
|
||||
<script language="JavaScript">
|
||||
var player = spbtvplayer('my-video', {
|
||||
log: true,
|
||||
features: {
|
||||
api: true,
|
||||
drm: false,
|
||||
metrics: true
|
||||
},
|
||||
apiConfig: {
|
||||
channelId: 'dash-widevine-vod',
|
||||
urlGetParams: 'minheight=400',
|
||||
clientId: null,
|
||||
movieId: null,
|
||||
episodeId: null,
|
||||
newsId: null,
|
||||
// apiHost: 'localhost:8080',
|
||||
},
|
||||
uiConfig: {
|
||||
initAsLive: true
|
||||
},
|
||||
globalOpts: {
|
||||
uiLanguage: 'ru'
|
||||
},
|
||||
streamOpts: {
|
||||
autoplay: true
|
||||
},
|
||||
controls: {
|
||||
externalSubtitles: {
|
||||
url: "https://raw.githubusercontent.com/videojs/video.js/c7298d40a4632a6e9dfcd5a2f5cc3bbe92a78744/docs/examples/elephantsdream/captions.ru.vtt",
|
||||
lang: 'ru'
|
||||
},
|
||||
zoomButton: {
|
||||
isVisible: true,
|
||||
enable: true,
|
||||
},
|
||||
editing: {
|
||||
enable: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
player.afterInitialize(() => {
|
||||
console.log("afterInitialize")
|
||||
player.setControlbarVisibility(false)
|
||||
})
|
||||
|
||||
player.addEventListener('play', onPlay, window)
|
||||
player.addEventListener('pause', onPause, window)
|
||||
player.addEventListener('canplay', onCanPlay, window)
|
||||
player.addEventListener('controlbarShow', onControlsShow, window)
|
||||
player.addEventListener('controlbarHide', oncontrolsHide, window)
|
||||
|
||||
function onPlay() { console.log("on PLAY") }
|
||||
|
||||
function onPause() { console.log("on PAUSE") }
|
||||
|
||||
function onCanPlay() { console.log("on CANPLAY") }
|
||||
|
||||
function onControlsShow() { console.log("on onControlsShow") }
|
||||
|
||||
function oncontrolsHide() { console.log("on oncontrolsHide") }
|
||||
|
||||
//
|
||||
function controlBarHide() {
|
||||
player.setControlbarVisibility(false)
|
||||
}
|
||||
|
||||
function controlBarShow() {
|
||||
player.setControlbarVisibility(true)
|
||||
}
|
||||
|
||||
function changeQualityAuto() {
|
||||
player.setSelectedVideoQuality(-1)
|
||||
}
|
||||
|
||||
function changeQualityLowest() {
|
||||
player.setSelectedVideoQuality(0)
|
||||
}
|
||||
|
||||
function changeQualityBest() {
|
||||
var quality = player.getVideoQualityList()
|
||||
player.setSelectedVideoQuality(quality.length - 1)
|
||||
}
|
||||
|
||||
function setDubAudioTrack() {
|
||||
player.setCurrentAudioTrack(1)
|
||||
}
|
||||
|
||||
function setEngAudioTrack() {
|
||||
player.setCurrentAudioTrack(0)
|
||||
}
|
||||
|
||||
function disableSubs() {
|
||||
player.setCurrentSubtitlesTrack(-1)
|
||||
}
|
||||
|
||||
function setDeSubs() {
|
||||
player.setCurrentSubtitlesTrack(0)
|
||||
}
|
||||
|
||||
function setEnSubs() {
|
||||
player.setCurrentSubtitlesTrack(1)
|
||||
}
|
||||
|
||||
const fireEvents = [
|
||||
'play',
|
||||
'pause',
|
||||
'canplay',
|
||||
'ended',
|
||||
// 'timeupdate',
|
||||
'error',
|
||||
'volumechange',
|
||||
'controlbarShow',
|
||||
'controlbarHide',
|
||||
'qualityChange',
|
||||
'sourceAttached',
|
||||
'zoomButtonChange',
|
||||
'trackChange',
|
||||
'bufferLengthUpdate',
|
||||
'zoomModeChange',
|
||||
'toolboxStartSel',
|
||||
'toolboxEndSel',
|
||||
'toolboxProcessSel',
|
||||
'destroyed',
|
||||
'bufferingUpdate',
|
||||
'timeshiftUpdate',
|
||||
]
|
||||
|
||||
function currentTime() {
|
||||
const d = new Date()
|
||||
const h = `${d.getHours()}`.padStart(2, '0')
|
||||
const m = `${d.getMinutes()}`.padStart(2, '0')
|
||||
const s = `${d.getSeconds()}`.padStart(2, '0')
|
||||
return h + ":" + m + ":" + s
|
||||
}
|
||||
|
||||
function addLog (message) {
|
||||
const element = document.createElement('div')
|
||||
element.classList.add('log-item')
|
||||
element.innerHTML = '<b class="current-time">' + currentTime() + '</b> ' + message;
|
||||
document.querySelector("#logs").prepend(element)
|
||||
}
|
||||
|
||||
fireEvents.forEach(event => {
|
||||
player.addEventListener(event, (payload) => {
|
||||
addLog (`<i>${event}</i> : ${JSON.stringify(payload)}`)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
.logs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 600px;
|
||||
border: 1px solid gray;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" style="width: 100%; height: 100%">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
|
||||
<script language="JavaScript" src="./distribution/vokaPlayer.global.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<body style="width: 100%; height: 100%">
|
||||
<h1>Hello world</h1>
|
||||
<div id="my-video"></div>
|
||||
<div id="my-video" style="width: 100%; height: 100%"></div>
|
||||
<button onclick="controlBarShow()" type="button">SHOW CONTROL BAR</button>
|
||||
<button onclick="controlBarHide()" type="button">HIDE CONTROL BAR</button>
|
||||
<button onclick="changeQualityAuto()" type="button">AUTO QUALITY</button>
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
movieId: null,
|
||||
episodeId: null,
|
||||
newsId: null,
|
||||
apiHost: 'localhost:8080',
|
||||
},
|
||||
uiConfig: {
|
||||
initAsLive: true
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<body>
|
||||
<h1>Hello world</h1>
|
||||
<p>
|
||||
Демка показывает возможность воспроизведения hls widevine vod
|
||||
Демка показывает возможность воспроизведения hls fairplay vod
|
||||
</p>
|
||||
<p>
|
||||
Исходник https://hlsjs.video-dev.org/demo/?src=https%3A%2F%2Fstorage.googleapis.com%2Fshaka-demo-assets%2Fangel-one-widevine-hls%2Fhls.m3u8&demoConfig=eyJlbmFibGVTdHJlYW1pbmciOnRydWUsImF1dG9SZWNvdmVyRXJyb3IiOnRydWUsInN0b3BPblN0YWxsIjpmYWxzZSwiZHVtcGZNUDQiOmZhbHNlLCJsZXZlbENhcHBpbmciOi0xLCJsaW1pdE1ldHJpY3MiOi0xfQ==
|
||||
@@ -29,7 +29,6 @@
|
||||
movieId: null,
|
||||
episodeId: null,
|
||||
newsId: null,
|
||||
apiHost: 'localhost:8080',
|
||||
},
|
||||
uiConfig: {
|
||||
initAsLive: true
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
movieId: null,
|
||||
episodeId: null,
|
||||
newsId: null,
|
||||
apiHost: 'localhost:8080',
|
||||
},
|
||||
uiConfig: {
|
||||
initAsLive: true
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
|
||||
<script language="JavaScript" src="./distribution/vokaPlayer.global.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world</h1>
|
||||
<div id="my-video"></div>
|
||||
<button onclick="controlBarShow()" type="button">SHOW CONTROL BAR</button>
|
||||
<button onclick="controlBarHide()" type="button">HIDE CONTROL BAR</button>
|
||||
<button onclick="changeQualityAuto()" type="button">AUTO QUALITY</button>
|
||||
<button onclick="changeQualityLowest()" type="button">LOWEST QUALITY</button>
|
||||
<button onclick="changeQualityBest()" type="button">BEST QUALITY</button>
|
||||
<button onclick="setEngAudioTrack()" type="button">ENGLISH AUDIO</button>
|
||||
<button onclick="setDubAudioTrack()" type="button">DUBBING AUDIO</button>
|
||||
<button onclick="disableSubs()" type="button">DISABLE SUBS</button>
|
||||
<button onclick="setDeSubs()" type="button">DEUTCH SUBS</button>
|
||||
<button onclick="setEnSubs()" type="button">ENGLISH SUBS</button>
|
||||
<h2>Logs</h2>
|
||||
<div id="logs" class="logs"></div>
|
||||
<script language="JavaScript">
|
||||
var player = spbtvplayer('my-video', {
|
||||
log: true,
|
||||
features: {
|
||||
api: true,
|
||||
drm: false,
|
||||
metrics: true
|
||||
},
|
||||
apiConfig: {
|
||||
channelId: 'hls-998f5396-c9dd-4a1e-82c7-0aec531fc015',
|
||||
urlGetParams: 'minheight=400',
|
||||
clientId: null,
|
||||
movieId: null,
|
||||
episodeId: null,
|
||||
newsId: null,
|
||||
// apiHost: 'localhost:8080',
|
||||
},
|
||||
uiConfig: {
|
||||
initAsLive: true
|
||||
},
|
||||
globalOpts: {
|
||||
uiLanguage: 'ru'
|
||||
},
|
||||
streamOpts: {
|
||||
autoplay: true
|
||||
},
|
||||
controls: {
|
||||
externalSubtitles: {
|
||||
url: "https://raw.githubusercontent.com/videojs/video.js/c7298d40a4632a6e9dfcd5a2f5cc3bbe92a78744/docs/examples/elephantsdream/captions.ru.vtt",
|
||||
lang: 'ru'
|
||||
},
|
||||
zoomButton: {
|
||||
isVisible: true,
|
||||
enable: true,
|
||||
},
|
||||
editing: {
|
||||
enable: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
player.afterInitialize(() => {
|
||||
console.log("afterInitialize")
|
||||
player.setControlbarVisibility(false)
|
||||
})
|
||||
|
||||
player.addEventListener('play', onPlay, window)
|
||||
player.addEventListener('pause', onPause, window)
|
||||
player.addEventListener('canplay', onCanPlay, window)
|
||||
player.addEventListener('controlbarShow', onControlsShow, window)
|
||||
player.addEventListener('controlbarHide', oncontrolsHide, window)
|
||||
|
||||
function onPlay() { console.log("on PLAY") }
|
||||
|
||||
function onPause() { console.log("on PAUSE") }
|
||||
|
||||
function onCanPlay() { console.log("on CANPLAY") }
|
||||
|
||||
function onControlsShow() { console.log("on onControlsShow") }
|
||||
|
||||
function oncontrolsHide() { console.log("on oncontrolsHide") }
|
||||
|
||||
//
|
||||
function controlBarHide() {
|
||||
player.setControlbarVisibility(false)
|
||||
}
|
||||
|
||||
function controlBarShow() {
|
||||
player.setControlbarVisibility(true)
|
||||
}
|
||||
|
||||
function changeQualityAuto() {
|
||||
player.setSelectedVideoQuality(-1)
|
||||
}
|
||||
|
||||
function changeQualityLowest() {
|
||||
player.setSelectedVideoQuality(0)
|
||||
}
|
||||
|
||||
function changeQualityBest() {
|
||||
var quality = player.getVideoQualityList()
|
||||
player.setSelectedVideoQuality(quality.length - 1)
|
||||
}
|
||||
|
||||
function setDubAudioTrack() {
|
||||
player.setCurrentAudioTrack(1)
|
||||
}
|
||||
|
||||
function setEngAudioTrack() {
|
||||
player.setCurrentAudioTrack(0)
|
||||
}
|
||||
|
||||
function disableSubs() {
|
||||
player.setCurrentSubtitlesTrack(-1)
|
||||
}
|
||||
|
||||
function setDeSubs() {
|
||||
player.setCurrentSubtitlesTrack(0)
|
||||
}
|
||||
|
||||
function setEnSubs() {
|
||||
player.setCurrentSubtitlesTrack(1)
|
||||
}
|
||||
|
||||
const fireEvents = [
|
||||
'play',
|
||||
'pause',
|
||||
'canplay',
|
||||
'ended',
|
||||
// 'timeupdate',
|
||||
'error',
|
||||
'volumechange',
|
||||
'controlbarShow',
|
||||
'controlbarHide',
|
||||
'qualityChange',
|
||||
'sourceAttached',
|
||||
'zoomButtonChange',
|
||||
'trackChange',
|
||||
'bufferLengthUpdate',
|
||||
'zoomModeChange',
|
||||
'toolboxStartSel',
|
||||
'toolboxEndSel',
|
||||
'toolboxProcessSel',
|
||||
'destroyed',
|
||||
'bufferingUpdate',
|
||||
'timeshiftUpdate',
|
||||
]
|
||||
|
||||
function currentTime() {
|
||||
const d = new Date()
|
||||
const h = `${d.getHours()}`.padStart(2, '0')
|
||||
const m = `${d.getMinutes()}`.padStart(2, '0')
|
||||
const s = `${d.getSeconds()}`.padStart(2, '0')
|
||||
return h + ":" + m + ":" + s
|
||||
}
|
||||
|
||||
function addLog (message) {
|
||||
const element = document.createElement('div')
|
||||
element.classList.add('log-item')
|
||||
element.innerHTML = '<b class="current-time">' + currentTime() + '</b> ' + message;
|
||||
document.querySelector("#logs").prepend(element)
|
||||
}
|
||||
|
||||
fireEvents.forEach(event => {
|
||||
player.addEventListener(event, (payload) => {
|
||||
addLog (`<i>${event}</i> : ${JSON.stringify(payload)}`)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
.logs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 600px;
|
||||
border: 1px solid gray;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"data": {
|
||||
"url": "https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p.mpd",
|
||||
"drm": {
|
||||
"type": "playready",
|
||||
"license_server": "https://drm-playready-licensing.axtest.net/AcquireLicense"
|
||||
},
|
||||
"adv1": "https://cdn.theoplayer.com/demos/ads/vmap/single-pre-mid-post-no-skip.xml",
|
||||
"subtitles": "https://raw.githubusercontent.com/videojs/video.js/c7298d40a4632a6e9dfcd5a2f5cc3bbe92a78744/docs/examples/elephantsdream/captions.ru.vtt",
|
||||
"analytics_v2": {
|
||||
"url": "https://juraldinio.com/analytics/",
|
||||
"interval": 5000,
|
||||
"additional_parameters": {
|
||||
"application_id": "42",
|
||||
"user_id": "12321",
|
||||
"resource_type": "video",
|
||||
"watch_session_id": "100500"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"data": {
|
||||
"url": "https://streaming-iptv.voka.tv/eyJvc19uYW1lIjoibWFjIG9zIiwidXNlcl91aWQiOiIzMDE4ZmM2Yi02YmY4LTQ4OGQtOGRhMi02YjZmNWFmMjFjNDQiLCJkYXRhY2VudGVyIjoiaW50IiwiZG9tYWluX25hbWUiOiJzdHJlYW1pbmctaXB0di52b2thLnR2IiwiZHJtIjoid2lkZXZpbmUiLCJleHBpcmF0aW9uX2RhdGUiOiIyMDI1LTA3LTMxVDIwOjUxOjEzWiIsImlwX2FkZHJlc3MiOiIxODUuMTM1LjE1MC40MCIsInByb2plY3QiOiJ2b2thX3Byb2R1Y3Rpb24iLCJwcm90b2NvbCI6ImRhc2giLCJzZXNzaW9uX2lkIjoiM2MzYTkxMjMtY2VkZi00ODdmLWI4MzItZjhkYjNmNWZkMmY0Iiwic3RyZWFtX25hbWUiOiI1ODMiLCJzdHJlYW1fcGF0aCI6Ii9pcF92NSJ9/MCwCFAaa_NjyUSswHJxTYp3hATrVF-cFAhQFUugUrPqnUOYfpnkl5RuhIAcuSA%3D%3D/ip_v5/583.mpd?b_app_channel_id=7e8cedbe-5f18-4649-8468-dd5af597a670&b_app_id=voka_production&b_device_platform=mac%20os&b_device_uid=1d866e05-b0e5-e943-f49c-295ac85c20d7&b_stream_sid=3c3a9123-cedf-487f-b832-f8db3f5fd2f4&b_strmr_channel_id=583&stream_dvr_window=10800000000 ",
|
||||
"url": "https://streaming-iptv.voka.tv/eyJvc19uYW1lIjoibWFjIG9zIiwidXNlcl91aWQiOiIzMDE4ZmM2Yi02YmY4LTQ4OGQtOGRhMi02YjZmNWFmMjFjNDQiLCJkYXRhY2VudGVyIjoiaW50IiwiZG9tYWluX25hbWUiOiJzdHJlYW1pbmctaXB0di52b2thLnR2IiwiZHJtIjoic3BidHZjYXMiLCJleHBpcmF0aW9uX2RhdGUiOiIyMDI1LTA4LTAzVDE3OjQxOjU0WiIsImlwX2FkZHJlc3MiOiI4OS4xMTAuMTIyLjE3NSIsInByb2plY3QiOiJ2b2thX3Byb2R1Y3Rpb24iLCJwcm90b2NvbCI6ImRhc2giLCJzZXNzaW9uX2lkIjoiNzkzNmJmY2EtZTA1ZS00NjJjLWE1MTQtZTU3NTk0MmY2ZDc2Iiwic3RyZWFtX25hbWUiOiI1ODMiLCJzdHJlYW1fcGF0aCI6Ii9pcF92NSJ9/MCwCFHXIZystCP_74eXig9GDBoGggAxjAhRGzvQFAovCN4VwluftKYV6tBmWFQ%3D%3D/ip_v5/583.mpd?b_app_channel_id=7e8cedbe-5f18-4649-8468-dd5af597a670&b_app_id=voka_production&b_device_platform=mac%20os&b_device_uid=1d866e05-b0e5-e943-f49c-295ac85c20d7&b_stream_sid=7936bfca-e05e-462c-a514-e575942f6d76&b_strmr_channel_id=583&stream_dvr_window=10800000000",
|
||||
"drm": {
|
||||
"type": "widevine",
|
||||
"license_server": "https://drmproxy.voka.tv"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"data": {
|
||||
"url-1": "https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p.mpd",
|
||||
"url": "https://media.axprod.net/TestVectors/Dash/protected_dash_1080p_h264_singlekey/manifest.mpd",
|
||||
"drm": {
|
||||
"type": "widevine",
|
||||
"license_server": "https://drm-widevine-licensing.axtest.net/AcquireLicense"
|
||||
},
|
||||
"adv1": "https://cdn.theoplayer.com/demos/ads/vmap/single-pre-mid-post-no-skip.xml",
|
||||
"subtitles": "https://raw.githubusercontent.com/videojs/video.js/c7298d40a4632a6e9dfcd5a2f5cc3bbe92a78744/docs/examples/elephantsdream/captions.ru.vtt",
|
||||
"analytics_v2": {
|
||||
"url": "https://juraldinio.com/analytics/",
|
||||
"interval": 5000,
|
||||
"additional_parameters": {
|
||||
"application_id": "42",
|
||||
"user_id": "12321",
|
||||
"resource_type": "video",
|
||||
"watch_session_id": "100500"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,26 @@
|
||||
{
|
||||
"data": {
|
||||
"url2": "http://mirrors.standaloneinstaller.com/video-sample/jellyfish-25-mbps-hd-hevc.mp4",
|
||||
"urlq": "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8",
|
||||
"url": "https://cdn.bitmovin.com/content/assets/sintel/hls/playlist.m3u8",
|
||||
"url-simple": "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3/gear1/prog_index.m3u8",
|
||||
"url": "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8",
|
||||
"url-dash": "https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd",
|
||||
"url-blocked": "https://cdn.bitmovin.com/content/assets/sintel/hls/playlist.m3u8",
|
||||
"url-hls-videwine-vod": "https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8",
|
||||
"drm-hls-videwine-vod": {
|
||||
"type": "widevine",
|
||||
"license_server": "https://cwip-shaka-proxy.appspot.com/no_auth"
|
||||
},
|
||||
"dash-widevine": "mark",
|
||||
"url-dash-widevine": "https://media.axprod.net/TestVectors/Dash/protected_dash_1080p_h264_singlekey/manifest.mpd",
|
||||
"drm-dash-widevine": {
|
||||
"type": "widevine",
|
||||
"license_server": "https://drm-widevine-licensing.axtest.net/AcquireLicense"
|
||||
},
|
||||
"drm-dash-playready": {
|
||||
"type": "playready",
|
||||
"license_server": "https://drm-playready-licensing.axprod.net/AcquireLicense"
|
||||
},
|
||||
"url-hls-live": "https://dai.google.com/linear/hls/event/rtcMlf4RTvOEkaudeany5w/master.m3u8?iu=/4128/CBS.NY.OTT",
|
||||
"adv1": "https://cdn.theoplayer.com/demos/ads/vmap/single-pre-mid-post-no-skip.xml",
|
||||
"subtitles": "https://raw.githubusercontent.com/videojs/video.js/c7298d40a4632a6e9dfcd5a2f5cc3bbe92a78744/docs/examples/elephantsdream/captions.ru.vtt",
|
||||
"analytics_v2": {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
server:
|
||||
image: docker.io/library/voka-player
|
||||
container_name: voka-player
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
restart: always
|
||||
volumes:
|
||||
- $PWD:/usr/voka
|
||||
- node_modules:/usr/voka/node_modules
|
||||
networks:
|
||||
- web
|
||||
labels:
|
||||
- "traefik.enable=false" # просто чтобы избежать конфликтов
|
||||
|
||||
caddy:
|
||||
image: caddy:2
|
||||
container_name: caddy
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
networks:
|
||||
- web
|
||||
|
||||
volumes:
|
||||
node_modules:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: $PWD/node_modules
|
||||
caddy_data: {}
|
||||
caddy_config: {}
|
||||
|
||||
networks:
|
||||
web:
|
||||
driver: bridge
|
||||
@@ -1,5 +1,6 @@
|
||||
.voka-poster {
|
||||
display: inline-block;
|
||||
z-index: -1000;
|
||||
vertical-align: middle;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 50%;
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
MediaPlayerErrorEvent,
|
||||
QualityChangeRenderedEvent, Representation,
|
||||
StreamInitializedEvent,
|
||||
} from 'dashjs'
|
||||
} from "dashjs";
|
||||
import {
|
||||
ComponentErrorInfo,
|
||||
VokaError,
|
||||
@@ -591,21 +591,11 @@ export default class VokaDash {
|
||||
view: any
|
||||
): MediaPlayerClass {
|
||||
const mediaPlayer = MediaPlayer().create()
|
||||
// For whatever reason, we need to call setTextDefaultEnabled(false) to get
|
||||
// VTT captions to show, even though we're doing virtually the same thing
|
||||
// in setup-text-tracks.js
|
||||
// @TODO разобраться, почему нет такого метода
|
||||
// mediaPlayer.setTextDefaultEnabled(false)
|
||||
|
||||
// mediaPlayer.extend('HTTPLoader', HTTPLoader, true)
|
||||
|
||||
// Must run controller before these two lines or else there is no
|
||||
// element to bind to.
|
||||
mediaPlayer.initialize()
|
||||
mediaPlayer.setProtectionData(keySystemOptions)
|
||||
|
||||
this.attachListeners(mediaPlayer)
|
||||
|
||||
//Хотя что мы вообще собираемся посылать?
|
||||
// Apply all dash options that are set
|
||||
if (options) {
|
||||
Object.keys(options).forEach((key) => {
|
||||
@@ -632,17 +622,7 @@ export default class VokaDash {
|
||||
})
|
||||
}
|
||||
|
||||
mediaPlayer.attachView(view)
|
||||
|
||||
// Dash.js autoplays by default, video.js will handle autoplay
|
||||
mediaPlayer.setAutoPlay(false)
|
||||
|
||||
// Setup text tracks
|
||||
//setupTextTracks.call(null, this.player, tech, options)
|
||||
|
||||
// Attach the source with any protection data
|
||||
mediaPlayer.setProtectionData(keySystemOptions)
|
||||
mediaPlayer.attachSource(manifestSource)
|
||||
mediaPlayer.initialize(view, manifestSource, false)
|
||||
|
||||
this.player.trigger(VokaEvent.MasterDashPlaylistLoad, manifestSource)
|
||||
|
||||
@@ -702,6 +682,14 @@ export default class VokaDash {
|
||||
this.setBufferingComplete,
|
||||
this
|
||||
)
|
||||
mediaPlayer.on(
|
||||
'public_keySystemSelected',
|
||||
e => console.log("Key system selected: ", e),
|
||||
)
|
||||
mediaPlayer.on(
|
||||
'public_keyAdded',
|
||||
e => console.log("Key added:", e),
|
||||
)
|
||||
}
|
||||
|
||||
private updateBufferingMode(value: boolean) {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
import {
|
||||
IVokaSource,
|
||||
TizenSourceParams,
|
||||
TizenSourceProtection,
|
||||
WebOSSourceProtection,
|
||||
} from "@/internal/player/native/VokaSourceHandler";
|
||||
import videojs from 'video.js'
|
||||
import Player from 'video.js/dist/types/player'
|
||||
import chromecastPlugin from '@silvermine/videojs-chromecast/'
|
||||
@@ -251,80 +257,93 @@ namespace VokaCorePlayer {
|
||||
throw new Error('Empty content URL')
|
||||
}
|
||||
|
||||
let playableContent = null
|
||||
const drmTypes = {
|
||||
[DRMType.WIDEVINE]: 'com.widevine.alpha',
|
||||
[DRMType.PLAYREADY]: 'com.microsoft.playready',
|
||||
[DRMType.FAIRPLAY]: 'com.apple.fps',
|
||||
}
|
||||
let playableContent: IVokaSource = null
|
||||
const drm = content.drmConfig
|
||||
switch(content.type) {
|
||||
case VokaContentType.HLS:
|
||||
playableContent = {
|
||||
sourceType: "application/vnd.apple.mpegurl",
|
||||
}
|
||||
} as IVokaSource
|
||||
|
||||
if (!drm) break
|
||||
switch (drm.type) {
|
||||
case DRMType.WIDEVINE:
|
||||
playableContent["drmSystems"] = {
|
||||
'com.widevine.alpha': {
|
||||
licenseUrl: drm.certificateUrl,
|
||||
}
|
||||
const drmTypeString = drmTypes[drm.type]
|
||||
if (!drmTypeString) break
|
||||
|
||||
if (drm.type === DRMType.FAIRPLAY) {
|
||||
// hls.js
|
||||
playableContent.drmSystems = {
|
||||
[drmTypeString]: {
|
||||
certificateUrl: drm.certificateUrl,
|
||||
licenseUrl: drm.licenseUrl
|
||||
}
|
||||
break
|
||||
case DRMType.PLAYREADY:
|
||||
playableContent["drmSystems"] = {
|
||||
'com.microsoft.playready': {
|
||||
licenseUrl: drm.certificateUrl,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// hls.js
|
||||
playableContent.drmSystems = {
|
||||
[drmTypeString]: {
|
||||
licenseUrl: drm.certificateUrl
|
||||
}
|
||||
break
|
||||
// Подержка FP в hls.js
|
||||
case DRMType.FAIRPLAY:
|
||||
playableContent["drmSystems"] = {
|
||||
'com.apple.fps': {
|
||||
certificateUrl: drm.certificateUrl,
|
||||
licenseUrl: drm.licenseUrl,
|
||||
}
|
||||
}
|
||||
// WebOS native
|
||||
playableContent.webOSProtection = {
|
||||
licenseServer: drm.certificateUrl
|
||||
} as WebOSSourceProtection
|
||||
// Tizen native
|
||||
playableContent.tizenParams = {
|
||||
protection: {
|
||||
type: drm.type,
|
||||
licenseServer: drm.certificateUrl
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
case VokaContentType.MP4:
|
||||
playableContent = {
|
||||
sourceType: "video/mp4",
|
||||
} as TizenSourceParams
|
||||
}
|
||||
break
|
||||
case VokaContentType.DASH:
|
||||
case VokaContentType.WIDEVINE:
|
||||
case VokaContentType.PLAYREADY:
|
||||
playableContent = {
|
||||
sourceType: "application/dash+xml",
|
||||
}
|
||||
break
|
||||
case VokaContentType.WIDEVINE:
|
||||
if (drm != null && drm.type == DRMType.WIDEVINE) {
|
||||
playableContent = {
|
||||
sourceType: "application/dash+xml",
|
||||
keySystemOptions: [{
|
||||
name: "com.widevine.alpha",
|
||||
options: {
|
||||
serverURL: drm.certificateUrl,
|
||||
httpRequestHeaders: drm.headers,
|
||||
priority: 0,
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
break
|
||||
case VokaContentType.PLAYREADY:
|
||||
if (drm != null && drm.type == DRMType.PLAYREADY) {
|
||||
playableContent = {
|
||||
sourceType: "application/dash+xml",
|
||||
keySystemOptions: [{
|
||||
name: "com.microsoft.playready",
|
||||
options: {
|
||||
serverURL: drm.certificateUrl,
|
||||
httpRequestHeaders: drm.headers,
|
||||
priority: 0,
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
break
|
||||
} as IVokaSource;
|
||||
|
||||
if (!drm) break;
|
||||
const allowedDrmTypes = [DRMType.WIDEVINE, DRMType.PLAYREADY];
|
||||
|
||||
if (!allowedDrmTypes.includes(drm.type)) break;
|
||||
// dash.js
|
||||
playableContent.keySystemOptions = [{
|
||||
name: drmTypes[drm.type],
|
||||
options: {
|
||||
serverURL: drm.certificateUrl,
|
||||
// Доп. заголовки, например, авторизация запсроса к серверу лицензий
|
||||
// httpRequestHeaders: {
|
||||
// "X-AxDRM-Message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJ2ZXJzaW9uIjogMSwKICAiY29tX2tleV9pZCI6ICI2OWU1NDA4OC1lOWUwLTQ1MzAtOGMxYS0xZWI2ZGNkMGQxNGUiLAogICJtZXNzYWdlIjogewogICAgInR5cGUiOiAiZW50aXRsZW1lbnRfbWVzc2FnZSIsCiAgICAidmVyc2lvbiI6IDIsCiAgICAibGljZW5zZSI6IHsKICAgICAgImFsbG93X3BlcnNpc3RlbmNlIjogdHJ1ZQogICAgfSwKICAgICJjb250ZW50X2tleXNfc291cmNlIjogewogICAgICAiaW5saW5lIjogWwogICAgICAgIHsKICAgICAgICAgICJpZCI6ICI0MDYwYTg2NS04ODc4LTQyNjctOWNiZi05MWFlNWJhZTFlNzIiLAogICAgICAgICAgImVuY3J5cHRlZF9rZXkiOiAid3QzRW51dVI1UkFybjZBRGYxNkNCQT09IiwKICAgICAgICAgICJ1c2FnZV9wb2xpY3kiOiAiUG9saWN5IEEiCiAgICAgICAgfQogICAgICBdCiAgICB9LAogICAgImNvbnRlbnRfa2V5X3VzYWdlX3BvbGljaWVzIjogWwogICAgICB7CiAgICAgICAgIm5hbWUiOiAiUG9saWN5IEEiLAogICAgICAgICJwbGF5cmVhZHkiOiB7CiAgICAgICAgICAibWluX2RldmljZV9zZWN1cml0eV9sZXZlbCI6IDE1MCwKICAgICAgICAgICJwbGF5X2VuYWJsZXJzIjogWwogICAgICAgICAgICAiNzg2NjI3RDgtQzJBNi00NEJFLThGODgtMDhBRTI1NUIwMUE3IgogICAgICAgICAgXQogICAgICAgIH0KICAgICAgfQogICAgXQogIH0KfQ.l8PnZznspJ6lnNmfAE9UQV532Ypzt1JXQkvrk8gFSRw"
|
||||
// },
|
||||
httpRequestHeaders: drm.headers,
|
||||
priority: 0,
|
||||
},
|
||||
},
|
||||
];
|
||||
// WebOS native
|
||||
playableContent.webOSProtection = {
|
||||
licenseServer: drm.certificateUrl,
|
||||
} as WebOSSourceProtection;
|
||||
// Tizen native
|
||||
playableContent.tizenParams = {
|
||||
protection: {
|
||||
type: drm.type,
|
||||
licenseServer: drm.certificateUrl,
|
||||
// Доп. заголовки, например, авторизация запроса к серверу лицензий
|
||||
// В виде строки, разделитель заголовков - \n
|
||||
// httpHeader:
|
||||
// "X-AxDRM-Message:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJ2ZXJzaW9uIjogMSwKICAiY29tX2tleV9pZCI6ICI2OWU1NDA4OC1lOWUwLTQ1MzAtOGMxYS0xZWI2ZGNkMGQxNGUiLAogICJtZXNzYWdlIjogewogICAgInR5cGUiOiAiZW50aXRsZW1lbnRfbWVzc2FnZSIsCiAgICAidmVyc2lvbiI6IDIsCiAgICAibGljZW5zZSI6IHsKICAgICAgImFsbG93X3BlcnNpc3RlbmNlIjogdHJ1ZQogICAgfSwKICAgICJjb250ZW50X2tleXNfc291cmNlIjogewogICAgICAiaW5saW5lIjogWwogICAgICAgIHsKICAgICAgICAgICJpZCI6ICI0MDYwYTg2NS04ODc4LTQyNjctOWNiZi05MWFlNWJhZTFlNzIiLAogICAgICAgICAgImVuY3J5cHRlZF9rZXkiOiAid3QzRW51dVI1UkFybjZBRGYxNkNCQT09IiwKICAgICAgICAgICJ1c2FnZV9wb2xpY3kiOiAiUG9saWN5IEEiCiAgICAgICAgfQogICAgICBdCiAgICB9LAogICAgImNvbnRlbnRfa2V5X3VzYWdlX3BvbGljaWVzIjogWwogICAgICB7CiAgICAgICAgIm5hbWUiOiAiUG9saWN5IEEiLAogICAgICAgICJwbGF5cmVhZHkiOiB7CiAgICAgICAgICAibWluX2RldmljZV9zZWN1cml0eV9sZXZlbCI6IDE1MCwKICAgICAgICAgICJwbGF5X2VuYWJsZXJzIjogWwogICAgICAgICAgICAiNzg2NjI3RDgtQzJBNi00NEJFLThGODgtMDhBRTI1NUIwMUE3IgogICAgICAgICAgXQogICAgICAgIH0KICAgICAgfQogICAgXQogIH0KfQ.l8PnZznspJ6lnNmfAE9UQV532Ypzt1JXQkvrk8gFSRw"
|
||||
},
|
||||
} as TizenSourceParams;
|
||||
|
||||
break;
|
||||
// Нативный FP (Safari & iOS)
|
||||
case VokaContentType.FAIRPLAY:
|
||||
if (drm != null && drm.type == DRMType.FAIRPLAY) {
|
||||
@@ -335,14 +354,20 @@ namespace VokaCorePlayer {
|
||||
certificateUrl: drm.certificateUrl,
|
||||
licenseUrl: drm.licenseUrl,
|
||||
},
|
||||
}
|
||||
} as IVokaSource
|
||||
}
|
||||
break
|
||||
case VokaContentType.AES:
|
||||
playableContent = {
|
||||
sourceType: "application/vnd.apple.mpegurl",
|
||||
}
|
||||
} as IVokaSource
|
||||
break
|
||||
case VokaContentType.MP4:
|
||||
playableContent = {
|
||||
sourceType: "video/mp4",
|
||||
} as IVokaSource
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
if (playableContent != null) {
|
||||
@@ -410,7 +435,7 @@ namespace VokaCorePlayer {
|
||||
|
||||
// Create main container for player.
|
||||
const playerContainer = Dom.createEl(
|
||||
'object',
|
||||
'div',
|
||||
{ id: `${DivID}` },
|
||||
{}
|
||||
)
|
||||
|
||||
@@ -23,6 +23,8 @@ interface WebOSSourceProtection {
|
||||
interface TizenSourceProtection {
|
||||
type: string
|
||||
licenseServer: string
|
||||
// ex: "X-AxDRM-Message:" + DRMToken
|
||||
httpHeader: string
|
||||
}
|
||||
interface TizenSourceParams {
|
||||
protection: TizenSourceProtection | null
|
||||
@@ -41,8 +43,9 @@ interface IVokaSource {
|
||||
sourceType: string
|
||||
src: string
|
||||
startSeconds: number | null
|
||||
// Dash WideVine only
|
||||
// dash.js DRM options (widevine, playready only)
|
||||
keySystemOptions: [{ [key: string]: any }] | null
|
||||
// FirePlay для Apple native
|
||||
protection: AppleSourceProtection | null
|
||||
webOSProtection: WebOSSourceProtection | null
|
||||
tizenParams: TizenSourceParams | null
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace AVPlayHelper {
|
||||
}
|
||||
|
||||
export interface IAVPlayer {
|
||||
get lastError(): any
|
||||
get avState(): State
|
||||
get state(): State
|
||||
get eventsEmitter(): EventBus
|
||||
get currentTime(): number
|
||||
@@ -61,6 +63,7 @@ namespace AVPlayHelper {
|
||||
class AVPlayer implements IAVPlayer {
|
||||
|
||||
private readonly avPlayer: any
|
||||
private _lastError: any
|
||||
private _state: State
|
||||
private _bus: EventBus
|
||||
private _currentTime: number
|
||||
@@ -74,51 +77,64 @@ namespace AVPlayHelper {
|
||||
this._currentTime = 0
|
||||
this.isPrebufferPlaying = false
|
||||
|
||||
console.log("✨ avplay initialized " + this.avPlayer.getVersion())
|
||||
console.log("AVplay initialized " + this.avPlayer.getVersion())
|
||||
}
|
||||
|
||||
private addListener(avPlayer: any) {
|
||||
if (AVPlayer.isAllowedState(this.state, State.idle) == null) { return }
|
||||
avPlayer.setListener({
|
||||
oncurrentplaytime: (currentTime) => {
|
||||
console.log("[AVPlayHelper] oncurrentplaytime : ", currentTime)
|
||||
this._currentTime = currentTime
|
||||
this._bus.publish(
|
||||
Events.time({time: this.currentTime, player: this})
|
||||
)
|
||||
},
|
||||
onevent: (eventType, eventData) => { console.log("event type: " + eventType + ", data: " + eventData) },
|
||||
onevent: (eventType, eventData) => {
|
||||
console.log("[AVPlayHelper] event type: " + eventType + ", data: " + eventData)
|
||||
},
|
||||
onbufferingstart: () => {
|
||||
// console.log("Buffering start.")
|
||||
console.log("[AVPlayHelper] Buffering start.")
|
||||
this.isPrebufferPlaying = this.state == State.playing
|
||||
},
|
||||
onbufferingprogress: (percent) => { console.log("Buffering progress data : " + percent) },
|
||||
onbufferingprogress: (percent) => {
|
||||
console.log("[AVPlayHelper] Buffering progress data : " + percent)
|
||||
},
|
||||
onbufferingcomplete: () => {
|
||||
this.switchState(State.ready)
|
||||
if (this.isPrebufferPlaying) {
|
||||
this.isPrebufferPlaying = false
|
||||
this.avPlayer.play()
|
||||
}
|
||||
console.log("Buffering complete.")
|
||||
console.log("[AVPlayHelper] Buffering complete. avState, avPlayer ", this.avState, this.avPlayer)
|
||||
},
|
||||
onrenderingstart: () => {
|
||||
console.log('[AVPlayHelper] onRenderingStart');
|
||||
|
||||
},
|
||||
onstreamcompleted: () => {
|
||||
console.log("Stream Completed")
|
||||
console.log("[AVPlayHelper] Stream Completed")
|
||||
this.isPrebufferPlaying = false
|
||||
this.stop(false)
|
||||
},
|
||||
onsubtitlechange: (duration, text, data3, data4) => {
|
||||
console.log("subtitleText: " + text)
|
||||
console.log("[AVPlayHelper] subtitleText: " + text)
|
||||
},
|
||||
onerror: (eventType) => {
|
||||
console.log("event type error : " + eventType)
|
||||
this._lastError = eventType
|
||||
console.log("[AVPlayHelper] event type error : " + eventType)
|
||||
},
|
||||
ondrmevent: (drmEvent, drmData) => {
|
||||
console.log("DRM callback: " + drmEvent + ", data: " + drmData)
|
||||
console.log("[AVPlayHelper] DRM callback: ", drmEvent, drmData)
|
||||
},
|
||||
onerrormsg: (err, msg) => console.error("[AVPlayHelper] onerrormsg:", err, msg),
|
||||
})
|
||||
}
|
||||
|
||||
private switchState(state: State) {
|
||||
const arrived = AVPlayer.isAllowedState(this._state, state)
|
||||
if (arrived == null) {
|
||||
console.log("Not allowed transition from " + this._state + " to " + state)
|
||||
console.log("[AVPlayHelper] switchState Not allowed transition from " + this._state + " to " + state)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -126,6 +142,7 @@ namespace AVPlayHelper {
|
||||
this._bus.publish(
|
||||
Events.state({state: arrived, player: this})
|
||||
)
|
||||
console.log("[AVPlayHelper] Transition from " + this._state + " to " + state)
|
||||
}
|
||||
|
||||
// https://developer.samsung.com/media/2893/avplay_18082017fw.png
|
||||
@@ -147,13 +164,13 @@ namespace AVPlayHelper {
|
||||
if ([State.playing, State.paused].includes(arrive)) return arrive
|
||||
break
|
||||
}
|
||||
console.log("🌚 " + depart + " -> " + arrive)
|
||||
console.log("[AVPlayHelper] isAllowedState Not allowed state transition: " + depart + " -> " + arrive)
|
||||
return null
|
||||
}
|
||||
|
||||
private requiredState(state: State): boolean {
|
||||
if (this.state != state) {
|
||||
console.error("🐣 Incorrect state: " + this.state)
|
||||
console.error("[AVPlayHelper] requiredState incorrect state: ", this.state, state)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -161,7 +178,7 @@ namespace AVPlayHelper {
|
||||
|
||||
private requireAllowedStates(states: State[]): boolean {
|
||||
if (!states.includes(this.state)) {
|
||||
console.error("🐣 Incorrect state: " + this.state)
|
||||
console.error("[AVPlayHelper] requireAllowedStates incorrect state: ", this.state, states, )
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -169,7 +186,17 @@ namespace AVPlayHelper {
|
||||
|
||||
// MARK: - IAVPlay
|
||||
|
||||
get state(): State { return this._state }
|
||||
get lastError(): any { return this._lastError }
|
||||
|
||||
get avState(): State {
|
||||
console.log("[AVPlayHelper] avState: ", this.avPlayer.getState())
|
||||
return this.avPlayer.getState()
|
||||
}
|
||||
|
||||
get state(): State {
|
||||
// console.log("[AVPlayHelper] state: _state, avState ", this._state, this.avState)
|
||||
return this._state
|
||||
}
|
||||
|
||||
get eventsEmitter(): EventBus { return this._bus }
|
||||
get currentTime(): number { return this._currentTime / 1000 }
|
||||
@@ -179,14 +206,17 @@ namespace AVPlayHelper {
|
||||
get isPlaying(): boolean { return this.state == State.playing }
|
||||
|
||||
open(url: string) {
|
||||
if (AVPlayer.isAllowedState(this.state, State.idle) == null) { return }
|
||||
if (AVPlayer.isAllowedState(this.state, State.idle) == null) {
|
||||
return
|
||||
}
|
||||
console.log('[AVPlayHelper] open', url)
|
||||
this.avPlayer.open(url)
|
||||
this.switchState(State.idle)
|
||||
|
||||
this.addListener(this.avPlayer)
|
||||
}
|
||||
|
||||
prepare(): Promise<void> {
|
||||
console.log('[AVPlayHelper] prepare');
|
||||
if (!this.requiredState(State.idle)) {
|
||||
return Promise.reject('incorrect state')
|
||||
}
|
||||
@@ -195,21 +225,30 @@ namespace AVPlayHelper {
|
||||
this.avPlayer.prepareAsync(
|
||||
() => {
|
||||
this.switchState(State.ready)
|
||||
console.log('[AVPlayHelper] prepareAsync completed: _state, avState', this._state, this.avState);
|
||||
resolve()
|
||||
},
|
||||
(error) => { reject('prepareAsync failed: ' + error) }
|
||||
(error) => {
|
||||
console.log('[AVPlayHelper] prepareFailed: ', error, this.avState);
|
||||
console.log('[AVPlayHelper] prepareFailed stack: ', error.stack);
|
||||
reject('prepare failed: ' + error)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
play() {
|
||||
if (AVPlayer.isAllowedState(this.state, State.playing) == null) { return }
|
||||
console.log('[AVPlayHelper] play');
|
||||
if (AVPlayer.isAllowedState(this.state, State.playing) == null) {
|
||||
console.log('[AVPlayHelper] play invalid transition', this.state, State.playing);
|
||||
return
|
||||
}
|
||||
try {
|
||||
this.avPlayer.play()
|
||||
this.switchState(State.playing)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
console.error("[AVPlayHelper] play error: ", error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +258,7 @@ namespace AVPlayHelper {
|
||||
this.avPlayer.pause()
|
||||
this.switchState(State.paused)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
console.error("[AVPlayHelper] pause error: ",error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +267,7 @@ namespace AVPlayHelper {
|
||||
try {
|
||||
this.avPlayer.seekTo(seconds * 1000)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
console.error("[AVPlayHelper] seekTo error: ", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,16 +287,22 @@ namespace AVPlayHelper {
|
||||
|
||||
drmOptions(properties: any) {
|
||||
if (!this.requiredState(State.idle)) { return }
|
||||
this.avPlayer.setDrm(
|
||||
'PLAYREADY',
|
||||
'SetProperties',
|
||||
JSON.stringify(properties)
|
||||
)
|
||||
console.log("[drmOptions] setDrm properties:", properties)
|
||||
try {
|
||||
this.avPlayer.setDrm(
|
||||
'PLAYREADY',
|
||||
'SetProperties',
|
||||
JSON.stringify(properties)
|
||||
)
|
||||
} catch (e) {
|
||||
console.log("[drmOptions] setDrm error", e)
|
||||
}
|
||||
}
|
||||
|
||||
setDisplayRect(x: number, y: number, width: number, heigth: number) {
|
||||
setDisplayRect(x: number, y: number, width: number, height: number) {
|
||||
if (!this.requiredState(State.idle)) { return }
|
||||
this.avPlayer.setDisplayRect(0, 0, 1920, 1080)
|
||||
console.log('[AVPlayHelper] setDisplayRect', x, y, width, height);
|
||||
this.avPlayer.setDisplayRect(x, y, width, height)
|
||||
}
|
||||
|
||||
setDisplayMethod(method: string) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DeviceInfo, Stream } from "@/internal/player/native/tizen/models/PlayerLoadParameters";
|
||||
import videojs from 'video.js'
|
||||
import VokaTizenSourceHandler from '../sourcehandler/VokaTizenSourceHandler'
|
||||
import AVPlayHelper from './AVPlayHelper'
|
||||
@@ -24,7 +25,7 @@ class VokaTizenTech extends Tech {
|
||||
private startTime: number | null
|
||||
private switchToThisTime: number | null
|
||||
|
||||
constructor(player, options, ready) {
|
||||
constructor(options, ready) {
|
||||
const opt = options || {}
|
||||
opt.techId = VokaTizenTech.TECH_NAME
|
||||
super(opt, ready)
|
||||
@@ -48,6 +49,10 @@ class VokaTizenTech extends Tech {
|
||||
|
||||
this.attachListeners(this.avPlayer)
|
||||
|
||||
if (options.source) {
|
||||
this.setSource(options.source);
|
||||
}
|
||||
|
||||
this.triggerReady() // from Component
|
||||
}
|
||||
|
||||
@@ -76,6 +81,10 @@ class VokaTizenTech extends Tech {
|
||||
case AVPlayHelper.State.paused:
|
||||
this.trigger('pause')
|
||||
break
|
||||
case AVPlayHelper.State.ready:
|
||||
this.trigger('durationchange');
|
||||
this.trigger('canplay')
|
||||
break
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -88,9 +97,10 @@ class VokaTizenTech extends Tech {
|
||||
const el = document.createElement(this.elementTagName)
|
||||
el.id = playerId
|
||||
el.setAttribute('type', 'application/avplayer')
|
||||
el.setAttribute('id', 'av-player')
|
||||
el.style.width = '100%'
|
||||
el.style.height = '100%'
|
||||
el.setAttribute('className', 'vjs-tech tizen-avplay-tech')
|
||||
el.style.width = '100vw'
|
||||
el.style.height = '100vh'
|
||||
|
||||
this.el_ = el
|
||||
return el
|
||||
}
|
||||
@@ -115,7 +125,6 @@ class VokaTizenTech extends Tech {
|
||||
|
||||
reset() {
|
||||
this.screenSaver.enable()
|
||||
|
||||
this.startTime = null
|
||||
this.selectedAudioTrack = null
|
||||
this.params = null
|
||||
@@ -136,8 +145,8 @@ class VokaTizenTech extends Tech {
|
||||
loop() { return false }
|
||||
setLoop(value) { }
|
||||
|
||||
seeking() { return false }
|
||||
seekable() { return false }
|
||||
seeking() { return true }
|
||||
seekable() { return true }
|
||||
|
||||
preload() { }
|
||||
setPreload(preload) { }
|
||||
@@ -149,13 +158,20 @@ class VokaTizenTech extends Tech {
|
||||
const src = typeof source.src === 'undefined' ? '' : source.src
|
||||
const sourceType = typeof source.sourceType === 'undefined' ? '' : source.sourceType
|
||||
let parameters = source.tizenParams
|
||||
console.log("[VokaTizenTech.setSrc] source ", source)
|
||||
if (parameters == null) {
|
||||
parameters = {} as TizenSourceParams
|
||||
parameters = {} as TizenSourceParams
|
||||
}
|
||||
if (typeof parameters.isUHDSupported !== "boolean") {
|
||||
parameters.isUHDSupported = true
|
||||
parameters.platform = {}
|
||||
}
|
||||
if (!parameters.platform) {
|
||||
parameters.platform = {} as DeviceInfo
|
||||
}
|
||||
if (!parameters?.stream) {
|
||||
parameters.stream = {
|
||||
url: src,
|
||||
}
|
||||
url: src
|
||||
} as Stream
|
||||
}
|
||||
|
||||
this.is4KSupported = parameters.isUHDSupported
|
||||
@@ -170,7 +186,7 @@ class VokaTizenTech extends Tech {
|
||||
|
||||
if (!this.is4KSupported) {
|
||||
if (supportedBandWidthCount === 0) {
|
||||
//onError(event, PlayerAccessError.CannotPlayStream);
|
||||
console.log("[VokaTizenTech] No supported BandWidth", playListsAttributes)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -183,20 +199,12 @@ class VokaTizenTech extends Tech {
|
||||
.split('.')[0], 10)
|
||||
const playerUrl = parameters.stream.url
|
||||
|
||||
// if (getProtocolByStreamURL(playerUrl) === Protocol.HLS) {
|
||||
// playerUrl += '|COMPONENT=HLS';
|
||||
// }
|
||||
const protection = parameters.protection
|
||||
const hasDRM = protection != null && protection.type == 'playready'
|
||||
console.log("[VokaTizenTech] setSrc: protection, hasDRM", protection, hasDRM)
|
||||
|
||||
this.avPlayer.open(playerUrl)
|
||||
|
||||
// if (seekTo !== undefined && !isNaN(seekTo)) {
|
||||
// webapis.avplay.seekTo(seekTo * 1000);
|
||||
//
|
||||
// switchToThisTime = null;
|
||||
// }
|
||||
|
||||
/*
|
||||
https://developer.samsung.com/smarttv/develop/guides/multimedia/media-playback/using-avplay.html#drm-contents-playback-sequence
|
||||
*/
|
||||
@@ -205,10 +213,19 @@ class VokaTizenTech extends Tech {
|
||||
DeleteLicenseAfterUse: true,
|
||||
LicenseServer: protection.licenseServer,
|
||||
}
|
||||
if (protection.httpHeader) {
|
||||
properties.HttpHeader = protection.httpHeader
|
||||
}
|
||||
this.avPlayer.drmOptions(properties)
|
||||
}
|
||||
|
||||
this.avPlayer.setDisplayRect(0, 0, 1920, 1080)
|
||||
const rect = this.el_.getBoundingClientRect()
|
||||
this.avPlayer.setDisplayRect(
|
||||
Math.round(rect.left),
|
||||
Math.round(rect.top),
|
||||
Math.round(rect.width),
|
||||
Math.round(rect.height)
|
||||
)
|
||||
this.avPlayer.setDisplayMethod('PLAYER_DISPLAY_MODE_AUTO_ASPECT_RATIO')
|
||||
|
||||
if (this.is4KSupported) {
|
||||
@@ -277,7 +294,7 @@ class VokaTizenTech extends Tech {
|
||||
this.avPlayer.seekTo(this.switchToThisTime)
|
||||
this.switchToThisTime = null
|
||||
} else if (parameters.percentsWatched) {
|
||||
this.avPlayer.seekTo(parameters.percentsWatched * this.getDuration() || 0)
|
||||
this.avPlayer.seekTo(parameters.percentsWatched * this.duration() || 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -286,18 +303,25 @@ class VokaTizenTech extends Tech {
|
||||
}
|
||||
|
||||
duration() {
|
||||
console.log("[VokaTizenTech] duration() started")
|
||||
const parameters = this.params
|
||||
if (parameters == null) { return }
|
||||
if (parameters == null) {
|
||||
console.log("[VokaTizenTech] duration is null")
|
||||
return
|
||||
}
|
||||
try {
|
||||
if (parameters.isLiveStream) {
|
||||
const [start, end] = this.avPlayer.getStreamingProperty('GET_LIVE_DURATION').split('|')
|
||||
const duration = this.avPlayer.duration
|
||||
console.log("[VokaTizenTech] duration(): start, end", start, end)
|
||||
return (
|
||||
duration > 0 ? duration : parseInt(end, 10) - parseInt(start, 10) || 0
|
||||
)
|
||||
}
|
||||
console.log("[VokaTizenTech] duration ", this.avPlayer.duration)
|
||||
return this.avPlayer.duration
|
||||
} catch (e) {
|
||||
console.error("[VokaTizenTech] Cant get duration", e)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,10 @@ export default class VokaWebOSSourceHandler extends VokaSourceHandler {
|
||||
|
||||
private createDRMPlayer(source: IVokaSource, tech: VokaWebOSTech): WebOSPlayerNativeDRM {
|
||||
const protection = source.webOSProtection
|
||||
if (protection == null) { return }
|
||||
if (protection == null) {
|
||||
console.log('[createDRMPlayer] cant get source.webOSProtection: source', source)
|
||||
return
|
||||
}
|
||||
|
||||
const config = {
|
||||
licenseServer: protection.licenseServer,
|
||||
|
||||
@@ -13,7 +13,7 @@ class VokaWebOSTech extends Tech {
|
||||
private lastCurrentTime: number | null
|
||||
private playPromise: null
|
||||
|
||||
constructor(player, options, ready) {
|
||||
constructor(options, ready) {
|
||||
const opt = options || {}
|
||||
opt.techId = VokaWebOSTech.TECH_NAME
|
||||
super(opt, ready)
|
||||
@@ -21,6 +21,10 @@ class VokaWebOSTech extends Tech {
|
||||
this.playPromise = null
|
||||
this.lastCurrentTime = null
|
||||
|
||||
if (options.source) {
|
||||
this.setSource(options.source);
|
||||
}
|
||||
|
||||
this.triggerReady()
|
||||
}
|
||||
|
||||
@@ -122,10 +126,10 @@ class VokaWebOSTech extends Tech {
|
||||
setLoop(value) { }
|
||||
|
||||
seeking() {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
seekable() {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
preload() { }
|
||||
@@ -157,7 +161,7 @@ class VokaWebOSTech extends Tech {
|
||||
currentSrc() { return '' }
|
||||
|
||||
duration() {
|
||||
return this.el().duration || 0
|
||||
return this.el().duration || 0
|
||||
}
|
||||
|
||||
setCurrentTime(seconds) {
|
||||
@@ -205,7 +209,7 @@ class VokaWebOSTech extends Tech {
|
||||
}
|
||||
|
||||
paused() {
|
||||
return false
|
||||
return this.el().paused
|
||||
}
|
||||
|
||||
ended() {
|
||||
|
||||
@@ -18,7 +18,10 @@ namespace VokaMagicRemotePlugin {
|
||||
PAUSE: 19,
|
||||
|
||||
NEXT: 417,
|
||||
PREV: 412
|
||||
PREV: 412,
|
||||
|
||||
TRACK_NEXT: 10233,
|
||||
TRACK_PREV: 10232
|
||||
}
|
||||
|
||||
export class Plugin extends VideoPlugin {
|
||||
@@ -53,10 +56,12 @@ namespace VokaMagicRemotePlugin {
|
||||
break
|
||||
case KEY_CODES.LEFT:
|
||||
case KEY_CODES.PREV:
|
||||
case KEY_CODES.TRACK_PREV:
|
||||
this.operationStepBackward()
|
||||
break
|
||||
case KEY_CODES.RIGHT:
|
||||
case KEY_CODES.NEXT:
|
||||
case KEY_CODES.TRACK_NEXT:
|
||||
this.operationStepForward()
|
||||
break
|
||||
}
|
||||
@@ -104,13 +109,18 @@ namespace VokaMagicRemotePlugin {
|
||||
}
|
||||
|
||||
private operationStepForward() {
|
||||
const skipTime = 5//this.options.skip?.forward
|
||||
console.log("[operationStepForward] started")
|
||||
const skipTime = 5 //this.options.skip?.forward
|
||||
if (isNaN(this.player.duration()) || !skipTime) {
|
||||
return
|
||||
}
|
||||
|
||||
const currentVideoTime = this.player.currentTime()
|
||||
|
||||
console.log("[operationStepForward] currentTime = ", currentVideoTime)
|
||||
|
||||
const liveTracker = this.player.liveTracker
|
||||
console.log("[operationStepForward] liveTracker, duration", liveTracker.isLive(), liveTracker.seekableEnd(), this.player.duration())
|
||||
const duration =
|
||||
liveTracker && liveTracker.isLive()
|
||||
? liveTracker.seekableEnd()
|
||||
@@ -123,6 +133,7 @@ namespace VokaMagicRemotePlugin {
|
||||
newTime = duration
|
||||
}
|
||||
|
||||
console.log("[operationStepForward] newTime = ", newTime)
|
||||
this.player.currentTime(newTime)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,10 @@ export class VokaPlayerImpl implements IVokaPlayer {
|
||||
// Логика для сайта voka - если нечего играть, плеер скрываем;
|
||||
player.load(iContent)
|
||||
.then(() => player.enable())
|
||||
.catch((error) => player.disable())
|
||||
.catch((error) => {
|
||||
console.error("Error content loading, disable player", error)
|
||||
player.disable()
|
||||
})
|
||||
}
|
||||
|
||||
private async initialize(player: VokaCorePlayer.CorePlayer, features: SupportedCodecs.ISelectProtocolResult): Promise<boolean> {
|
||||
|
||||
Reference in New Issue
Block a user