Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
2d4abc8
Changes for MK Player UI, temoporary comit before tryin iphone fix
binon Sep 4, 2024
f5fff25
Fix for iphone, need to test resource page
binon Sep 9, 2024
1779430
Updating MKPlayer controlbar
binon Sep 12, 2024
bafb166
New player UI, sorted play pause issuse
binon Sep 13, 2024
05e2515
MKPLayer implementation in Admin page
binon Sep 13, 2024
ca95e97
New MKPlayer Changes in Resource page
binon Sep 14, 2024
47663a9
New Player update in case/assement page
binon Sep 16, 2024
2fae38d
Fixed some of the resolution issues
binon Sep 16, 2024
47ae249
Merge pull request #582 from TechnologyEnhancedLearning/RC
binon Sep 16, 2024
9f054c7
Firefox fix
binon Sep 17, 2024
e8c62f0
TD-4486-AutoSuggestionWebLocalBackup
ArunimaGeorge Aug 19, 2024
4027df2
Reapply "TD-4486:latest changes"
ArunimaGeorge Sep 11, 2024
c1799c5
TD-4461: Auto Complete - As a learner, I want to the system to auto c…
ArunimaGeorge Sep 17, 2024
10f6200
TD-4461: removed blank spaces and added findwise settings for auto su…
ArunimaGeorge Sep 17, 2024
c019b3b
Added validation for video file
binon Sep 18, 2024
9d2e4d4
Video validaiton in landingpage
binon Sep 18, 2024
1256cb2
Merge pull request #584 from TechnologyEnhancedLearning/Develop/featu…
ArunimaGeorge Sep 19, 2024
483b906
Proxy fix for iphone
binon Sep 25, 2024
7120d33
Updated package file to fix error in devops
binon Sep 25, 2024
a1c3ea1
MKIO iphone fix
binon Oct 3, 2024
9b8ecbe
Refactored the mediacontroller
binon Oct 3, 2024
907bdcd
Merge branch 'releases/tucana' into Develop/Features/TD-4294-Video_Au…
binon Oct 3, 2024
e53f6c8
Merge pull request #629 from TechnologyEnhancedLearning/Develop/Featu…
binon Oct 3, 2024
bd2693e
removed trailing comment code
binon Oct 3, 2024
580fde0
Merge pull request #630 from TechnologyEnhancedLearning/RC
binon Oct 3, 2024
3d098aa
Reverting package.json changes to see whether it fixes the devops build
binon Oct 4, 2024
9e6aabd
Updated package file
binon Oct 4, 2024
f2e08c1
Update package.json, concurrency back
binon Oct 4, 2024
fda4e3d
Disabling Source Maps to fix the memory issue
binon Oct 7, 2024
830a3c4
bumping up sass version
binon Oct 8, 2024
619e84c
Forcing the memory size from package.json
binon Oct 8, 2024
7dea8a6
Reverted the size option upgraded node version in package.json
binon Oct 8, 2024
029d2f8
copying RC package.lock json to see whether it fixes the devops build…
binon Oct 8, 2024
71c2fea
Pushing adminui package lock json
binon Oct 8, 2024
fd1d3d5
TD-4256: Assessment and Case Resource - Allows to upload unsupported …
Swapnamol Oct 9, 2024
14ea3f8
Modified the script
Swapnamol Oct 9, 2024
990cb29
Merge pull request #639 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 10, 2024
c9b2311
Implemented the AdminUI proxy for iPhone
binon Oct 10, 2024
5852223
Fixed video rendering issue on Iphone on landing page
binon Oct 11, 2024
0c71eea
conflicts resolved
AnjuJose011 Oct 15, 2024
2f44a47
Merge pull request #649 from TechnologyEnhancedLearning/MergeRC-abelia3
AnjuJose011 Oct 15, 2024
d9ea055
TD-4870 : Implemented Did you Mean Feature for Search Search enhancem…
ArunimaGeorge Oct 22, 2024
f71a58c
Merge pull request #684 from TechnologyEnhancedLearning/RC
AnjuJose011 Oct 24, 2024
24340cc
Merge pull request #685 from TechnologyEnhancedLearning/releases/tucana
AnjuJose011 Oct 24, 2024
1c679fd
Merge pull request #687 from TechnologyEnhancedLearning/releases/LHAb…
AnjuJose011 Oct 24, 2024
ae5e5f2
Merge pull request #665 from TechnologyEnhancedLearning/Develop/Featu…
ArunimaGeorge Oct 24, 2024
b97dab8
Merge pull request #688 from TechnologyEnhancedLearning/releases/tucana
AnjuJose011 Oct 24, 2024
bd71b2e
modelversion update
AnjuJose011 Oct 24, 2024
0362235
Merge pull request #689 from TechnologyEnhancedLearning/updateModelve…
AnjuJose011 Oct 24, 2024
0ed0acd
modelupdate
AnjuJose011 Oct 24, 2024
ba725bb
Merge pull request #690 from TechnologyEnhancedLearning/BuildErrorFix…
AnjuJose011 Oct 24, 2024
034def8
conflicts resolved
AnjuJose011 Oct 24, 2024
c8882f4
conflicts resloved
AnjuJose011 Oct 24, 2024
5672130
Merge pull request #692 from TechnologyEnhancedLearning/MergeRctoTucana1
AnjuJose011 Oct 24, 2024
f9bb0cc
TD-4945: CORS Policy Issue on iPhone Landing Page
ArunimaGeorge Oct 25, 2024
ffa5ff0
TD-4944: UI Overlap on Mobile Devices
Swapnamol Oct 25, 2024
c80d844
Merge pull request #696 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 28, 2024
6d49b4a
Merge pull request #695 from TechnologyEnhancedLearning/Develop/Fixes…
ArunimaGeorge Oct 28, 2024
99365e4
TD-4251: Fixed title bold issue on safari.
ArunimaGeorge Oct 29, 2024
642bdde
Merge pull request #701 from TechnologyEnhancedLearning/Develop/Fixes…
ArunimaGeorge Oct 29, 2024
69928eb
WMV file included in the admin UI Information page also
Swapnamol Oct 29, 2024
8022229
Merge pull request #707 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 29, 2024
2a8e9bd
TD-4782 image processing fix
OluwatobiAwe Oct 30, 2024
8b0a253
Merge pull request #712 from TechnologyEnhancedLearning/Develop/Fixes…
OluwatobiAwe Oct 30, 2024
25039ae
TD-4944: Fixes for UI issues on Mobile view
Swapnamol Oct 31, 2024
e29455a
Merge pull request #718 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 31, 2024
2395bcc
Design fix
Swapnamol Oct 31, 2024
172822b
Merge pull request #720 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 31, 2024
fdd34fa
Design fixes
Swapnamol Oct 31, 2024
f3100ab
Merge pull request #721 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 31, 2024
cb6da19
design fix
Swapnamol Nov 1, 2024
4fad847
Merge pull request #724 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Nov 1, 2024
0591e7e
Css fixes for mobile devices
Swapnamol Nov 4, 2024
13cd133
Merge pull request #730 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Nov 4, 2024
693c1c5
CSS fixes
Swapnamol Nov 5, 2024
2891818
Revert "CSS fixes"
Swapnamol Nov 5, 2024
b33c737
Design fixes for the admin UI
Swapnamol Nov 5, 2024
3339cff
Footer design fixes
Swapnamol Nov 5, 2024
b3a3735
Merge pull request #732 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Nov 5, 2024
4393e59
TD-4870: Timeout page not showing properly in search page.
ArunimaGeorge Nov 8, 2024
88dac10
Merge pull request #736 from TechnologyEnhancedLearning/Develop/Fixes…
ArunimaGeorge Nov 8, 2024
6cc45f2
TD-4870: Fixed Timeout issue and mismatch in counts in ViewAllCatalog…
ArunimaGeorge Nov 14, 2024
87e5700
Merge pull request #740 from TechnologyEnhancedLearning/Develop/Fixes…
ArunimaGeorge Nov 15, 2024
83daccf
TD-4997: Video Contents in eLearning resources not getting played on …
Swapnamol Nov 15, 2024
fa1936f
Formatted
Swapnamol Nov 15, 2024
c6e1f70
Merge pull request #743 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Nov 15, 2024
e7e614e
Included triggers into the schema
Swapnamol Nov 15, 2024
75cc7ee
Merge pull request #744 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Nov 15, 2024
b73136b
TD-5036: Update Database Schema and Include Trigger
Swapnamol Nov 15, 2024
4b32656
Merge pull request #745 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Nov 15, 2024
cac9076
TD-4870: Change in did you mean suggestion message
ArunimaGeorge Nov 18, 2024
c881bdd
Merge pull request #746 from TechnologyEnhancedLearning/Develop/Fixes…
ArunimaGeorge Nov 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,27 @@ public string Get(string playBackUrl, string token)
{
using (var reader = new StreamReader(stream))
{
const string qualityLevelRegex = @"(QualityLevels\(\d+\))";
const string qualityLevelRegex = @"(|)([^""\s]+\.m3u8\(encryption=cbc\))";
const string fragmentsRegex = @"(Fragments\([\w\d=-]+,[\w\d=-]+\))";
const string urlRegex = @"("")(https?:\/\/[\da-z\.-]+\.[a-z\.]{2,6}[\/\w \.-]*\/?[\?&][^&=]+=[^&=#]*)("")";
const string urlRegex = @"(https?:\/\/[\da-z\.-]+\.[a-z\.]{2,6}[\/\w \.-]*\?[^,\s""]*)";

var baseUrl = playBackUrl.Substring(0, playBackUrl.IndexOf(".ism", System.StringComparison.OrdinalIgnoreCase)) + ".ism";
this.logger.LogDebug($"baseUrl={baseUrl}");

var content = reader.ReadToEnd();

var newContent = Regex.Replace(content, urlRegex, string.Format(CultureInfo.InvariantCulture, "$1$2&token={0}$3", token));
content = ReplaceUrisWithProxy(content, baseUrl);
var newContent = Regex.Replace(content, urlRegex, match =>
{
string baseUrlWithQuery = match.Groups[1].Value; // URL including the query string

// Append the token correctly without modifying surrounding characters
string newUrl = baseUrlWithQuery.Contains("?") ?
$"{baseUrlWithQuery}&token={token}" :
$"{baseUrlWithQuery}?token={token}";

return newUrl;
});
this.logger.LogDebug($"newContent={newContent}");

var match = Regex.Match(playBackUrl, qualityLevelRegex);
Expand All @@ -87,5 +98,33 @@ public string Get(string playBackUrl, string token)

return null;
}

private static string ReplaceUrisWithProxy(string playlistContent, string proxyUrl)
{
// Split the playlist content into lines
var lines = playlistContent.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);

// Process each line to replace media or map URIs
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].StartsWith("#EXT-X-MAP:URI=", StringComparison.OrdinalIgnoreCase))
{
// Extract the URI from the current line for EXT-X-MAP
var existingUri = lines[i].Substring(lines[i].IndexOf('=') + 1).Trim('"');
var newUri = $"{proxyUrl}/{existingUri}";
lines[i] = lines[i].Replace(existingUri, newUri);
}
else if (lines[i].StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase) && i + 1 < lines.Length)
{
// Get the URI from the next line for EXTINF
var existingUri = lines[i + 1].Trim();
var newUri = $"{proxyUrl}/{existingUri}";
lines[i + 1] = newUri;
}
}

// Join the modified lines back into a single string
return string.Join("\r\n", lines);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
<PackageReference Include="HtmlSanitizer" Version="6.0.453" />
<PackageReference Include="IdentityModel" Version="4.4.0" />
<PackageReference Include="LearningHub.Nhs.Caching" Version="2.0.2" />
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.41" />
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.43" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.19.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
import { AzureMediaAssetModel } from '../models/content/videoAssetModel';
import { MKPlayer } from '@mediakind/mkplayer';
import { MKPlayerType, MKStreamType } from '../MKPlayerConfigEnum';
//import { getPlayerConfig, getSourceConfig, initializePlayer } from '../mkiomediaplayer';
import { buildControlbar } from '../mkioplayer-controlbar';

export default Vue.extend({
props: {
Expand All @@ -89,14 +91,20 @@
player: null,
videoContainer: null,
mkioKey: '',
isIphone: false,
requestURL: ''
};
},
async created(): Promise<void> {
async created(): Promise<void> {
await this.getMKIOPlayerKey();
this.load();
this.getDisplayAVFlag();
this.getAudioVideoUnavailableView();
},
mounted() {
this.checkIfIphone();
this.requestURL = window.location.origin;
},
computed: {
getStyle() {
console.log("getLinkStyle", (this.pageSectionDetail || {}).draftHidden);
Expand Down Expand Up @@ -168,11 +176,37 @@
this.audioVideoUnavailableView = response;
});
},
//onSubtitleAdded() {
// this.player.subtitles.enable("subtitle" + this.section.id.toString());
//},
onPlayerReady() {
const videoElement = document.getElementById("bitmovinplayer-video-" + this.getPlayerUniqueId) as HTMLVideoElement;
if (videoElement) {
videoElement.controls = true;
}
var contanierId = this.section.id.toString();
var uniquePlayer = this.player;// ([email protected]);
buildControlbar(contanierId, uniquePlayer);

// [BY] When we set UI to false we need to manually add the controls to the video element
//const videoElement = document.getElementById("bitmovinplayer-video-" + this.getPlayerUniqueId) as HTMLVideoElement;
//if (videoElement) {
// videoElement.controls = true;
//}

// var subtitleTrack;
//if (this.pageSectionDetail.videoAsset.azureMediaAsset && this.pageSectionDetail.videoAsset.closedCaptionsFile) {
// const captionsInfo = this.pageSectionDetail.videoAsset.closedCaptionsFile;
// var srcPath = "file/download/" + captionsInfo.filePath + "/" + captionsInfo.fileName;
// //srcPath = '@requestURL' + srcPath;
// srcPath = "https://bitdash-a.akamaihd.net/content/sintel/subtitles/subtitles_en.vtt";

// subtitleTrack = {
// id: "subtitle" + this.section.id.toString(),
// lang: "en",
// label: "english",
// url: srcPath,
// kind: "subtitle"
// };
//};

//this.player.addSubtitle(subtitleTrack);
},
async getMKIOPlayerKey(): Promise<void> {
this.mkioKey = await contentData.getMKPlayerKey();
Expand All @@ -189,14 +223,14 @@
// Grab the video container
this.videoContainer = document.getElementById(this.getPlayerUniqueId);

if(!this.mkioKey) {
if (!this.mkioKey) {
this.getMKIOPlayerKey();
}

// Prepare the player configuration
const playerConfig = {
key: this.mkioKey,
ui: false,
ui: true,
playback: {
muted: false,
autoplay: false,
Expand All @@ -205,15 +239,33 @@
theme: "dark",
events: {
ready: this.onPlayerReady,
//subtitleadded: this.onSubtitleAdded,
}
};

// Initialize the player with video container and player configuration
this.player = new MKPlayer(this.videoContainer, playerConfig);

var subtitleTrack = null;
var sectionId = this.section.id.toString();
if (this.pageSectionDetail.videoAsset.azureMediaAsset && this.pageSectionDetail.videoAsset.closedCaptionsFile) {
var captionsInfo = this.pageSectionDetail.videoAsset.closedCaptionsFile;;

if (captionsInfo) {
var srcPath = "/file/download/" + captionsInfo.filePath + "/" + captionsInfo.fileName;
subtitleTrack = {
id: "subtitle" + sectionId,
lang: "en",
label: "english",
url: this.requestURL + srcPath,
kind: "subtitle"
};
}
}
// Load source
const sourceConfig = {
hls: this.getMediaPlayUrl(this.pageSectionDetail.videoAsset.azureMediaAsset.locatorUri),
subtitleTracks: [subtitleTrack],
drm: {
clearkey: {
LA_URL: "HLS_AES",
Expand Down Expand Up @@ -282,8 +334,18 @@
},
getMediaPlayUrl(url: string): string {
let sourceUrl = url.substring(0, url.lastIndexOf("manifest")) + "manifest(format=m3u8-cmaf,encryption=cbc)";

if (this.isIphone) {
var token = this.pageSectionDetail.videoAsset.azureMediaAsset.authenticationToken;
sourceUrl = "/Media/MediaManifest?playBackUrl=" + sourceUrl + "&token=" + token;
}

return sourceUrl;
},
checkIfIphone() {
const userAgent = navigator.userAgent || navigator.vendor;
this.isIphone = /iPhone/i.test(userAgent);
},
},
watch: {
section() {
Expand Down Expand Up @@ -318,4 +380,8 @@
video[id^="bitmovinplayer-video"] {
width: 100%;
}

.bmpui-ui-controlbar .control-right {
float: right;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div>
<div class="toolBarBox">
<div class="toolBar">
<div :style="getStatusStyle()" class="mr-4 p-3">
<div :style="getStatusStyle()" class="mr-1 p-2">
<i :class="contentLib.getPageSectionStatusIcon(this.pageSection.pageSectionDetail)"></i>
{{ contentLib.getPageSectionStatusText(this.pageSection.pageSectionDetail) }}
</div>
Expand Down Expand Up @@ -167,8 +167,8 @@
methods: {
getStatusStyle(): string {
return this.pageSection.pageSectionDetail.pageSectionStatus === PageSectionStatus.Live
? 'background: #007F3B; height: 45px; margin: -8px;border: 1px solid #FFFFFF;'
: ((this.pageSection.pageSectionDetail.deletePending == null || !this.pageSection.pageSectionDetail.deletePending) ? 'background: #FFB81C; height: 45px; margin: -8px;border: 1px solid #FFFFFF;color: #425563;' : 'background: #DA291C; height: 45px; margin: -8px; border: 1px solid #FFFFFF;');
? 'background: #007F3B; height: 50px; margin: -12px;border: 1px solid #FFFFFF;'
: ((this.pageSection.pageSectionDetail.deletePending == null || !this.pageSection.pageSectionDetail.deletePending) ? 'background: #FFB81C; height: 50px; margin: -12px;border: 1px solid #FFFFFF;color: #425563;' : 'background: #DA291C; height: 50px; margin: -12px; border: 1px solid #FFFFFF;');
},
getStatusIconStyle(): string {
return 'margin-top:20px;'
Expand Down Expand Up @@ -215,8 +215,9 @@

.toolBarBox {
position: absolute;
right: 20px;
top: 20px;
right: 12px;
left:10px;
top: 2px;
z-index: 1;
}

Expand All @@ -237,7 +238,7 @@
.toolBar {
display: flex;
padding: 16px;
height: 64px;
height: 60px;
float: right;
background: $nhsuk-grey;
border: 2px solid $nhsuk-white;
Expand Down Expand Up @@ -269,4 +270,14 @@
.toolBarButton i .fa, .fas {
font-weight: 100;
}
@media (max-width: 420px) {
.toolBarBox {
position: absolute;
right: 12px;
left: 10px;
top: 2px;
z-index: 1;
width: fit-content;
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const file_size_validation = (value: any) => {
export const file_extension_validation = (value: any) => {
if (!value) { return true; }
let fileExtension = value.name.split(".").pop();
let fileType = ['mp4', 'avi', 'm4v', 'mov', 'mkv', 'mpg', 'm2v', 'vob'].find(ext => ext == fileExtension);
let fileType = ['mp4', 'avi', 'm4v', 'mov', 'mkv', 'mpg', 'm2v', 'vob','wmv'].find(ext => ext == fileExtension);
return fileType != undefined;
};
export const transcriptfile_extension_validation = (value: any) => {
Expand Down
101 changes: 101 additions & 0 deletions AdminUI/LearningHub.Nhs.AdminUI/Scripts/vuesrc/mkiomediaplayer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { MKPlayer, MKPlayerConfig } from '@mediakind/mkplayer';
import { MKPlayerType, MKStreamType } from './MKPlayerConfigEnum';
interface ClearKeyConfig {
LA_URL: string;
headers: {
Authorization: string;
};
}

interface PlayerConfig {
key: string;
ui: boolean;
playback: {
muted: boolean;
autoplay: boolean;
preferredTech: Array<{ player: string; streaming: string }>;
};
theme: string;
events: {
ready: () => void;
};
}

interface SourceConfig {
hls: string;
drm: {
clearkey: ClearKeyConfig;
};
}

function getBearerToken(authenticationToken: string): string {
// Replace this with your actual logic to get the bearer token
return `Bearer ${authenticationToken}`;
}

function getPlayerConfig(
mkioKey: string,
onPlayerReady: () => void
): PlayerConfig {
return {
key: mkioKey,
ui: true,
playback: {
muted: false,
autoplay: false,
preferredTech: [{ player: "Html5", streaming: "Hls" }] // Adjust these strings if you have specific types
},
theme: "dark",
events: {
ready: onPlayerReady,
}
};
}

function getSourceConfig(
locatorUri: string,
authenticationToken: string
): SourceConfig {
return {
hls: locatorUri,
drm: {
clearkey: {
LA_URL: "HLS_AES",
headers: {
Authorization: getBearerToken(authenticationToken)
}
}
}
};
}

function initializePlayer(videoContainer: HTMLElement, playerConfig: MKPlayerConfig, playBackUrl: string, bearerToken: string): any {
const player = new MKPlayer(videoContainer, playerConfig);

var clearKeyConfig = {
//LA_URL: "https://ottapp-appgw-amp.prodc.mkio.tv3cloud.com/drm/clear-key?ownerUid=azuki",
LA_URL: "HLS_AES",
headers: {
"Authorization": bearerToken
}
};

const sourceConfig: SourceConfig = {
hls: playBackUrl,
drm: {
clearkey: clearKeyConfig
}
};

player.load(sourceConfig)
.then(() => {
console.log("Source loaded successfully!");
})
.catch(() => {
console.error("An error occurred while loading the source!");
});

return player;
};

export { getPlayerConfig, getSourceConfig, initializePlayer };
Loading
Loading