Commit 6c214e1b authored by John Rummell's avatar John Rummell Committed by Commit Bot

[eme] Add test for CBCS encrypted audio

Adds a new test file that is simply an audio stream fully encrypted with
'cbcs' encryption.

BUG=850679
TEST=new content_browsertests and browser_tests pass

Change-Id: I930af7aeb36cd4ccddab279849e3a84e6487bee3
Reviewed-on: https://chromium-review.googlesource.com/1093995
Commit-Queue: John Rummell <jrummell@chromium.org>
Reviewed-by: default avatarXiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#571539}
parent 5481b4c6
...@@ -56,6 +56,7 @@ const char kMp4Vp9VideoOnly[] = ...@@ -56,6 +56,7 @@ const char kMp4Vp9VideoOnly[] =
"video/mp4; codecs=\"vp09.00.10.08.01.02.02.02.00\""; "video/mp4; codecs=\"vp09.00.10.08.01.02.02.02.00\"";
#if BUILDFLAG(USE_PROPRIETARY_CODECS) #if BUILDFLAG(USE_PROPRIETARY_CODECS)
const char kMp4Avc1VideoOnly[] = "video/mp4; codecs=\"avc1.64001E\""; const char kMp4Avc1VideoOnly[] = "video/mp4; codecs=\"avc1.64001E\"";
const char kMp4AacAudioOnly[] = "audio/mp4; codecs=\"mp4a.40.2\"";
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) #endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
// EME-specific test results and errors. // EME-specific test results and errors.
...@@ -63,6 +64,7 @@ const char kEmeKeyError[] = "KEYERROR"; ...@@ -63,6 +64,7 @@ const char kEmeKeyError[] = "KEYERROR";
const char kEmeNotSupportedError[] = "NOTSUPPORTEDERROR"; const char kEmeNotSupportedError[] = "NOTSUPPORTEDERROR";
const char kDefaultEmePlayer[] = "eme_player.html"; const char kDefaultEmePlayer[] = "eme_player.html";
const char kDefaultMseOnlyEmePlayer[] = "mse_different_containers.html";
// The type of video src used to load media. // The type of video src used to load media.
enum class SrcType { SRC, MSE }; enum class SrcType { SRC, MSE };
...@@ -92,15 +94,14 @@ class EncryptedMediaTest ...@@ -92,15 +94,14 @@ class EncryptedMediaTest
void TestSimplePlayback(const std::string& encrypted_media, void TestSimplePlayback(const std::string& encrypted_media,
const std::string& media_type) { const std::string& media_type) {
RunSimpleEncryptedMediaTest(encrypted_media, media_type, CurrentKeySystem(), RunSimplePlaybackTest(encrypted_media, media_type, CurrentKeySystem(),
CurrentSourceType()); CurrentSourceType());
} }
void TestFrameSizeChange() { void TestFrameSizeChange() {
RunEncryptedMediaTest("encrypted_frame_size_change.html", RunTest("encrypted_frame_size_change.html",
"frame_size_change-av_enc-v.webm", "frame_size_change-av_enc-v.webm", kWebMVorbisAudioVp8Video,
kWebMVorbisAudioVp8Video, CurrentKeySystem(), CurrentKeySystem(), CurrentSourceType(), media::kEnded);
CurrentSourceType(), media::kEnded);
} }
void TestConfigChange(ConfigChangeType config_change_type) { void TestConfigChange(ConfigChangeType config_change_type) {
...@@ -121,12 +122,12 @@ class EncryptedMediaTest ...@@ -121,12 +122,12 @@ class EncryptedMediaTest
true); true);
} }
void RunEncryptedMediaTest(const std::string& html_page, void RunTest(const std::string& html_page,
const std::string& media_file, const std::string& media_file,
const std::string& media_type, const std::string& media_type,
const std::string& key_system, const std::string& key_system,
SrcType src_type, SrcType src_type,
const std::string& expectation) { const std::string& expectation) {
base::StringPairs query_params; base::StringPairs query_params;
query_params.emplace_back("mediaFile", media_file); query_params.emplace_back("mediaFile", media_file);
query_params.emplace_back("mediaType", media_type); query_params.emplace_back("mediaType", media_type);
...@@ -136,24 +137,40 @@ class EncryptedMediaTest ...@@ -136,24 +137,40 @@ class EncryptedMediaTest
RunMediaTestPage(html_page, query_params, expectation, true); RunMediaTestPage(html_page, query_params, expectation, true);
} }
void RunSimpleEncryptedMediaTest(const std::string& media_file, void RunSimplePlaybackTest(const std::string& media_file,
const std::string& media_type, const std::string& media_type,
const std::string& key_system, const std::string& key_system,
SrcType src_type) { SrcType src_type) {
RunEncryptedMediaTest(kDefaultEmePlayer, media_file, media_type, key_system, RunTest(kDefaultEmePlayer, media_file, media_type, key_system, src_type,
src_type, media::kEnded); media::kEnded);
} }
void TestMp4EncryptionPlayback(const std::string& media_file, void RunMultipleFileTest(const std::string& video_file,
const std::string& media_type, const std::string& video_type,
const std::string& expected_title) { const std::string& audio_file,
const std::string& audio_type,
const std::string& expected_title) {
if (CurrentSourceType() != SrcType::MSE) { if (CurrentSourceType() != SrcType::MSE) {
DVLOG(0) << "Skipping test; Can only play MP4 encrypted streams by MSE."; DVLOG(0) << "Skipping test; Can only play MP4 encrypted streams by MSE.";
return; return;
} }
RunEncryptedMediaTest(kDefaultEmePlayer, media_file, media_type, base::StringPairs query_params;
CurrentKeySystem(), SrcType::MSE, expected_title); query_params.emplace_back("keySystem", CurrentKeySystem());
query_params.emplace_back("runEncrypted", "1");
if (!video_file.empty()) {
DCHECK(!video_type.empty());
query_params.emplace_back("videoFile", video_file);
query_params.emplace_back("videoFormat", video_type);
}
if (!audio_file.empty()) {
DCHECK(!audio_type.empty());
query_params.emplace_back("audioFile", audio_file);
query_params.emplace_back("audioFormat", audio_type);
}
RunMediaTestPage(kDefaultMseOnlyEmePlayer, query_params, expected_title,
true);
} }
protected: protected:
...@@ -258,8 +275,8 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoClearAudio_WebM_Opus) { ...@@ -258,8 +275,8 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoClearAudio_WebM_Opus) {
} }
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioOnly_MP4_FLAC) { IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioOnly_MP4_FLAC) {
TestMp4EncryptionPlayback("bear-flac-cenc.mp4", kMp4FlacAudioOnly, RunMultipleFileTest(std::string(), std::string(), "bear-flac-cenc.mp4",
media::kEnded); kMp4FlacAudioOnly, media::kEnded);
} }
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_MP4_VP9) { IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_MP4_VP9) {
...@@ -302,32 +319,54 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, MAYBE_FrameSizeChangeVideo) { ...@@ -302,32 +319,54 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, MAYBE_FrameSizeChangeVideo) {
#if BUILDFLAG(USE_PROPRIETARY_CODECS) #if BUILDFLAG(USE_PROPRIETARY_CODECS)
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CENC) { IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CENC) {
TestMp4EncryptionPlayback("bear-640x360-v_frag-cenc.mp4", kMp4Avc1VideoOnly, RunMultipleFileTest("bear-640x360-v_frag-cenc.mp4", kMp4Avc1VideoOnly,
media::kEnded); "bear-640x360-a_frag-cenc.mp4", kMp4AacAudioOnly,
media::kEnded);
} }
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CBC1) { IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CBC1) {
TestMp4EncryptionPlayback("bear-640x360-v_frag-cbc1.mp4", kMp4Avc1VideoOnly, RunMultipleFileTest("bear-640x360-v_frag-cbc1.mp4", kMp4Avc1VideoOnly,
media::kError); std::string(), std::string(), media::kError);
} }
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CENS) { IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CENS) {
TestMp4EncryptionPlayback("bear-640x360-v_frag-cens.mp4", kMp4Avc1VideoOnly, RunMultipleFileTest("bear-640x360-v_frag-cens.mp4", kMp4Avc1VideoOnly,
media::kError); std::string(), std::string(), media::kError);
} }
#if !defined(OS_ANDROID)
// TODO(crbug.com/813845): Enable CBCS support on Chrome for Android.
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CBCS) { IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CBCS) {
std::string expected_result = std::string expected_result =
BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) ? media::kEnded : media::kError; BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) ? media::kEnded : media::kError;
TestMp4EncryptionPlayback("bear-640x360-v_frag-cbcs.mp4", kMp4Avc1VideoOnly, RunMultipleFileTest("bear-640x360-v_frag-cbcs.mp4", kMp4Avc1VideoOnly,
expected_result); "bear-640x360-a_frag-cbcs.mp4", kMp4AacAudioOnly,
expected_result);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest,
Playback_Encryption_CBCS_Video_CENC_Audio) {
std::string expected_result =
BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) ? media::kEnded : media::kError;
RunMultipleFileTest("bear-640x360-v_frag-cbcs.mp4", kMp4Avc1VideoOnly,
"bear-640x360-a_frag-cenc.mp4", kMp4AacAudioOnly,
expected_result);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest,
Playback_Encryption_CENC_Video_CBCS_Audio) {
std::string expected_result =
BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) ? media::kEnded : media::kError;
RunMultipleFileTest("bear-640x360-v_frag-cenc.mp4", kMp4Avc1VideoOnly,
"bear-640x360-a_frag-cbcs.mp4", kMp4AacAudioOnly,
expected_result);
} }
#endif // !defined(OS_ANDROID)
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) #endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, UnknownKeySystemThrowsException) { IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, UnknownKeySystemThrowsException) {
RunEncryptedMediaTest(kDefaultEmePlayer, "bear-a_enc-a.webm", RunTest(kDefaultEmePlayer, "bear-a_enc-a.webm", kWebMVorbisAudioOnly,
kWebMVorbisAudioOnly, "com.example.foo", SrcType::MSE, "com.example.foo", SrcType::MSE, kEmeNotSupportedError);
kEmeNotSupportedError);
} }
} // namespace content } // namespace content
...@@ -26,10 +26,17 @@ const char kWebMVideoOnly[] = "video/webm; codecs=\"vp8\""; ...@@ -26,10 +26,17 @@ const char kWebMVideoOnly[] = "video/webm; codecs=\"vp8\"";
const char kWebMAudioVideo[] = "video/webm; codecs=\"vorbis, vp8\""; const char kWebMAudioVideo[] = "video/webm; codecs=\"vorbis, vp8\"";
const char kMp4FlacAudioOnly[] = "audio/mp4; codecs=\"flac\""; const char kMp4FlacAudioOnly[] = "audio/mp4; codecs=\"flac\"";
#if BUILDFLAG(USE_PROPRIETARY_CODECS) && \ #if BUILDFLAG(USE_PROPRIETARY_CODECS)
BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) const char kMp4AudioOnly[] = "audio/mp4; codecs=\"mp4a.40.2\"'";
#if !defined(OS_ANDROID)
const char kMp4VideoOnly[] = "video/mp4; codecs=\"avc1.4D4041\"'";
#endif // !defined(OS_ANDROID)
#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
const char kMp2tAudioVideo[] = "video/mp2t; codecs=\"mp4a.40.2, avc1.42E01E\""; const char kMp2tAudioVideo[] = "video/mp2t; codecs=\"mp4a.40.2, avc1.42E01E\"";
#endif #endif // BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
namespace content { namespace content {
...@@ -103,8 +110,12 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, ConfigChangeVideo) { ...@@ -103,8 +110,12 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, ConfigChangeVideo) {
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_MP4_Audio_WEBM) { IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_MP4_Audio_WEBM) {
base::StringPairs query_params; base::StringPairs query_params;
query_params.push_back(std::make_pair("videoFormat", "CLEAR_MP4")); query_params.push_back(
query_params.push_back(std::make_pair("audioFormat", "CLEAR_WEBM")); std::make_pair("videoFile", "bear-640x360-v_frag.mp4"));
query_params.push_back(std::make_pair("videoFormat", kMp4VideoOnly));
query_params.push_back(
std::make_pair("audioFile", "bear-320x240-audio-only.webm"));
query_params.push_back(std::make_pair("audioFormat", kWebMAudioOnly));
RunMediaTestPage("mse_different_containers.html", query_params, media::kEnded, RunMediaTestPage("mse_different_containers.html", query_params, media::kEnded,
true); true);
} }
...@@ -112,8 +123,12 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_MP4_Audio_WEBM) { ...@@ -112,8 +123,12 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_MP4_Audio_WEBM) {
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_WEBM_Audio_MP4) { IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_WEBM_Audio_MP4) {
base::StringPairs query_params; base::StringPairs query_params;
query_params.push_back(std::make_pair("videoFormat", "CLEAR_WEBM")); query_params.push_back(
query_params.push_back(std::make_pair("audioFormat", "CLEAR_MP4")); std::make_pair("videoFile", "bear-320x240-video-only.webm"));
query_params.push_back(std::make_pair("videoFormat", kWebMVideoOnly));
query_params.push_back(
std::make_pair("audioFile", "bear-640x360-a_frag.mp4"));
query_params.push_back(std::make_pair("audioFormat", kMp4AudioOnly));
RunMediaTestPage("mse_different_containers.html", query_params, media::kEnded, RunMediaTestPage("mse_different_containers.html", query_params, media::kEnded,
true); true);
} }
......
...@@ -138,6 +138,10 @@ bear-640x360-v_frag-cens.mp4 ...@@ -138,6 +138,10 @@ bear-640x360-v_frag-cens.mp4
shaka/packager/tools/pssh/pssh-box.py --widevine-system-id --key-id 30313233343536373839303132333435 --hex shaka/packager/tools/pssh/pssh-box.py --widevine-system-id --key-id 30313233343536373839303132333435 --hex
shaka/packager/tools/pssh/pssh-box.py --common-system-id --key-id 30313233343536373839303132333435 --hex shaka/packager/tools/pssh/pssh-box.py --common-system-id --key-id 30313233343536373839303132333435 --hex
bear-640x360-a_frag-cbcs.mp4
- Same as previous instructions, except source is bear-640x360-a_frag.mp4
and no clear lead (i.e. --clear_lead 0).
bear-flac-cenc.mp4 bear-flac-cenc.mp4
- Encrypted version of bear-flac.mp4, encrypted by Shaka Packager - Encrypted version of bear-flac.mp4, encrypted by Shaka Packager
using key ID [1] and key [2]. Sample encryption information stored in using key ID [1] and key [2]. Sample encryption information stored in
......
...@@ -234,23 +234,11 @@ PlayerUtils.registerEMEEventListeners = function(player) { ...@@ -234,23 +234,11 @@ PlayerUtils.registerEMEEventListeners = function(player) {
} else { } else {
// Some tests (e.g. mse_different_containers.html) specify audio and // Some tests (e.g. mse_different_containers.html) specify audio and
// video codecs seperately. // video codecs seperately.
if (player.testConfig.videoFormat == 'ENCRYPTED_MP4' || if (player.testConfig.videoFormat) {
player.testConfig.videoFormat == 'CLEAR_MP4') { config.videoCapabilities = [{contentType: player.testConfig.videoFormat}];
config.videoCapabilities =
[{contentType: 'video/mp4; codecs="avc1.4D000C"'}];
} else if (
player.testConfig.videoFormat == 'ENCRYPTED_WEBM' ||
player.testConfig.videoFormat == 'CLEAR_WEBM') {
config.videoCapabilities = [{contentType: 'video/webm; codecs="vp8"'}];
} }
if (player.testConfig.audioFormat == 'ENCRYPTED_MP4' || if (player.testConfig.audioFormat) {
player.testConfig.audioFormat == 'CLEAR_MP4') { config.audioCapabilities = [{contentType: player.testConfig.audioFormat}];
config.audioCapabilities =
[{contentType: 'audio/mp4; codecs="mp4a.40.2"'}];
} else if (
player.testConfig.audioFormat == 'ENCRYPTED_WEBM' ||
player.testConfig.audioFormat == 'CLEAR_WEBM') {
config.audioCapabilities = [{contentType: 'audio/webm; codecs="vorbis"'}];
} }
} }
......
...@@ -6,32 +6,16 @@ ...@@ -6,32 +6,16 @@
<video></video> <video></video>
<script src='eme_player_js/app_loader.js' type='text/javascript'></script> <script src='eme_player_js/app_loader.js' type='text/javascript'></script>
<script type="text/javascript"> <script type="text/javascript">
// Specify possible content for clear and encrypted streams in both MP4
// and WEBM format. For testing we don't care if the audio matches the
// video or if the length of each container is the same.
var VIDEO_MP4_MEDIA_TYPE = 'video/mp4; codecs="avc1.4D4041"';
var VIDEO_WEBM_MEDIA_TYPE = 'video/webm; codecs="vp8"';
var VIDEO_MP4_CLEAR_FILE = 'bear-640x360-v_frag.mp4';
var VIDEO_WEBM_CLEAR_FILE = 'bear-320x240-video-only.webm';
var VIDEO_MP4_ENCRYPTED_FILE = 'bear-640x360-v_frag-cenc.mp4';
var VIDEO_WEBM_ENCRYPTED_FILE = 'bear-320x240-v_enc-v.webm';
var AUDIO_MP4_MEDIA_TYPE = 'audio/mp4; codecs="mp4a.40.2"'; // The time in secs to play the streams. Several encrypted streams have
var AUDIO_WEBM_MEDIA_TYPE = 'audio/webm; codecs="vorbis"'; // 1/2 second clear leads, so play at least a second to ensure that the
var AUDIO_MP4_CLEAR_FILE = 'bear-640x360-a_frag.mp4'; // encrypted content is handled.
var AUDIO_WEBM_CLEAR_FILE = 'bear-320x240-audio-only.webm'; var PLAY_TIME_SEC = 1.0;
var AUDIO_MP4_ENCRYPTED_FILE = 'bear-640x360-a_frag-cenc.mp4';
var AUDIO_WEBM_ENCRYPTED_FILE = 'bear-a_enc-a.webm';
var media_types = [];
var media_files = [];
// The time in secs to play the streams.
var PLAY_TIME_SEC = 0.1;
var video = document.querySelector('video'); var video = document.querySelector('video');
function onTimeUpdate() { function onTimeUpdate() {
Utils.timeLog('timeupdate @ ' + video.currentTime);
if (video.currentTime < PLAY_TIME_SEC) if (video.currentTime < PLAY_TIME_SEC)
return; return;
...@@ -39,44 +23,9 @@ ...@@ -39,44 +23,9 @@
video.removeEventListener('ended', Utils.failTest); video.removeEventListener('ended', Utils.failTest);
Utils.installTitleEventHandler(video, 'ended'); Utils.installTitleEventHandler(video, 'ended');
// Seek to end to save test execution time. // Seek to end to save test execution time. Most of the test videos
video.currentTime = 1000; // (e.g. the bear videos) are about 2.5 seconds long.
} video.currentTime = 3000;
function addVideoStream(format) {
if (format == 'CLEAR_MP4') {
media_types = media_types.concat(VIDEO_MP4_MEDIA_TYPE);
media_files = media_files.concat(VIDEO_MP4_CLEAR_FILE);
} else if (format == 'CLEAR_WEBM') {
media_types = media_types.concat(VIDEO_WEBM_MEDIA_TYPE);
media_files = media_files.concat(VIDEO_WEBM_CLEAR_FILE);
} else if (format == 'ENCRYPTED_MP4') {
media_types = media_types.concat(VIDEO_MP4_MEDIA_TYPE);
media_files = media_files.concat(VIDEO_MP4_ENCRYPTED_FILE);
} else if (format == 'ENCRYPTED_WEBM') {
media_types = media_types.concat(VIDEO_WEBM_MEDIA_TYPE);
media_files = media_files.concat(VIDEO_WEBM_ENCRYPTED_FILE);
} else {
Utils.failTest('Unrecognized video type.');
}
}
function addAudioStream(format) {
if (format == 'CLEAR_MP4') {
media_types = media_types.concat(AUDIO_MP4_MEDIA_TYPE);
media_files = media_files.concat(AUDIO_MP4_CLEAR_FILE);
} else if (format == 'CLEAR_WEBM') {
media_types = media_types.concat(AUDIO_WEBM_MEDIA_TYPE);
media_files = media_files.concat(AUDIO_WEBM_CLEAR_FILE);
} else if (format == 'ENCRYPTED_MP4') {
media_types = media_types.concat(AUDIO_MP4_MEDIA_TYPE);
media_files = media_files.concat(AUDIO_MP4_ENCRYPTED_FILE);
} else if (format == 'ENCRYPTED_WEBM') {
media_types = media_types.concat(AUDIO_WEBM_MEDIA_TYPE);
media_files = media_files.concat(AUDIO_WEBM_ENCRYPTED_FILE);
} else {
Utils.failTest('Unrecognized audio type.');
}
} }
function runTest() { function runTest() {
...@@ -85,8 +34,17 @@ ...@@ -85,8 +34,17 @@
var testConfig = new TestConfig(); var testConfig = new TestConfig();
testConfig.loadQueryParams(); testConfig.loadQueryParams();
addVideoStream(testConfig.videoFormat);
addAudioStream(testConfig.audioFormat); var media_types = [];
var media_files = [];
if (testConfig.videoFormat) {
media_types = media_types.concat(testConfig.videoFormat);
media_files = media_files.concat(testConfig.videoFile);
}
if (testConfig.audioFormat) {
media_types = media_types.concat(testConfig.audioFormat);
media_files = media_files.concat(testConfig.audioFile);
}
var mediaSource = var mediaSource =
MediaSourceUtils.loadMediaSource(media_files, media_types); MediaSourceUtils.loadMediaSource(media_files, media_types);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment