Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 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
702fc22
defectfix
AnjuJose011 Oct 15, 2024
d28c72a
Merge pull request #650 from TechnologyEnhancedLearning/TD-4891-Defec…
AnjuJose011 Oct 15, 2024
dc01d8c
Fixed the issue with the My learning tray. Also included the excluded…
Swapnamol Oct 16, 2024
514823f
Merge pull request #651 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 16, 2024
8e33214
excluded unwanted script
Swapnamol Oct 16, 2024
be3cc68
Merge pull request #652 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 16, 2024
f75df91
Update LearningHub.Nhs.Database.sqlproj
AnjuJose011 Oct 17, 2024
9051566
Deleted unwanted files
Swapnamol Oct 17, 2024
1d4eef4
To fix the issue with the statuses
Swapnamol Oct 18, 2024
26a07d6
Merge pull request #657 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 18, 2024
9bb0d7c
TD-2895: Modify Learning Resource endpoints to retrieve user status f…
Swapnamol Oct 21, 2024
2eb8423
Merge pull request #662 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 21, 2024
daa0c3d
Fixed the my learning tray issue
Swapnamol Oct 21, 2024
0c9073e
Merge pull request #663 from TechnologyEnhancedLearning/Develop/Fixes…
Swapnamol Oct 21, 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
722ef39
TD-4081:DIG306: Labels for form fields are missing
Swapnamol Oct 29, 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.40" />
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.42" />
<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>
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