Skip to content

Commit 5791f39

Browse files
authored
Merge pull request #11 from CeeblueTV/dev
getFile/getExtension/mediaExt/trim
2 parents a83b6a1 + 5462bcd commit 5791f39

File tree

2 files changed

+127
-8
lines changed

2 files changed

+127
-8
lines changed

src/Connect.ts

+59-6
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
44
* See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
55
*/
6-
import { NetAddress } from './NetAddress';
76
import * as Util from './Util';
7+
import { NetAddress } from './NetAddress';
88

99
/**
1010
* Parameters of connections
@@ -27,6 +27,11 @@ export type Params = {
2727
* iceServer to use while connecting to a WebRTC stream
2828
*/
2929
iceServer?: RTCIceServer; // Authentication value
30+
/**
31+
* Optional media extension (mp4, flv, ts, rts), usefull for protocol like WebRTS which supports different container type.
32+
* When not set, it's also an output parameter to indicate what is the media type selected
33+
*/
34+
mediaExt?: string;
3035
/**
3136
* Optional query to add into the generated url of connection
3237
*/
@@ -48,6 +53,56 @@ export enum Type {
4853
* Some connection utility functions
4954
*/
5055

56+
/**
57+
* Defines the {@link Params.mediaExt} based on the type of parameters and its endpoint.
58+
* This method always assigns a value to params.mediaExt, defaulting to an empty string if indeterminable,
59+
* allowing detection of whether the function has been applied to the parameters.
60+
* @param type The type of parameters to define.
61+
* @param params The parameters for which the media extension is to be defined
62+
*/
63+
export function defineMediaExt(type: Type, params: Params) {
64+
// Fix mediaExt in removing the possible '.' prefix
65+
if (params.mediaExt) {
66+
params.mediaExt = Util.trimStart(params.mediaExt, '.');
67+
}
68+
// Compute appropriate mediaExt out parameter
69+
switch (type) {
70+
case Type.HESP:
71+
params.mediaExt = 'mp4';
72+
break;
73+
case Type.WEBRTC:
74+
params.mediaExt = 'rtp';
75+
break;
76+
case Type.WRTS: {
77+
try {
78+
const url = new URL(params.endPoint);
79+
const ext = Util.getExtension(Util.getFile(url.pathname));
80+
// set extension just if not json, json means a manifest file endPoint
81+
if (ext && ext !== 'json') {
82+
params.mediaExt = ext;
83+
}
84+
} catch (_) {
85+
// not an URL, it's only a host => keep mediaExt unchanged to build the URL
86+
}
87+
if (!params.mediaExt) {
88+
// set to its default rts value => always set for WRTS!
89+
params.mediaExt = 'rts';
90+
}
91+
break;
92+
}
93+
case Type.META:
94+
params.mediaExt = 'js';
95+
break;
96+
case Type.DATA:
97+
params.mediaExt = 'json';
98+
break;
99+
default:
100+
params.mediaExt = ''; // set always a value to know that the parameters have been fixed
101+
console.warn('Unknown params type ' + type);
102+
break;
103+
}
104+
}
105+
51106
/**
52107
* Build an URL from {@link Type | type} and {@link Params | params}
53108
* @param type Type of the connection wanted
@@ -56,11 +111,9 @@ export enum Type {
56111
* @returns The URL of connection
57112
*/
58113
export function buildURL(type: Type, params: Params, protocol: string = 'wss'): URL {
59-
const url = new URL(NetAddress.fixProtocol(protocol, params.endPoint));
114+
defineMediaExt(type, params);
60115

61-
// Remove possible extension of streamName put sometimes to decide format when multiple choices are possible like with WRTS
62-
const ext = Util.parseExtension(params.streamName);
63-
params.streamName = params.streamName.substring(0, params.streamName.length - ext.length);
116+
const url = new URL(NetAddress.fixProtocol(protocol, params.endPoint));
64117

65118
if (url.pathname.length <= 1) {
66119
// build ceeblue path!
@@ -72,7 +125,7 @@ export function buildURL(type: Type, params: Params, protocol: string = 'wss'):
72125
url.pathname = '/webrtc/' + params.streamName;
73126
break;
74127
case Type.WRTS:
75-
url.pathname = '/wrts/' + params.streamName + ext;
128+
url.pathname = '/wrts/' + params.streamName;
76129
break;
77130
case Type.META:
78131
url.pathname = '/json_' + params.streamName + '.js';

src/Util.ts

+68-2
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,78 @@ export async function fetch(input: RequestInfo | URL, init?: RequestInit): Promi
272272
}
273273

274274
/**
275-
* Extension parser
275+
* Get Extension part from path
276276
* @param path path to parse
277277
* @returns the extension
278278
*/
279-
export function parseExtension(path: string): string {
279+
export function getExtension(path: string): string {
280280
const dot = path.lastIndexOf('.');
281281
const ext = dot >= 0 && dot > path.lastIndexOf('/') ? path.substring(dot) : '';
282282
return ext;
283283
}
284+
285+
/**
286+
* Get File part from path
287+
* @param path path to parse
288+
* @returns the file name
289+
*/
290+
export function getFile(path: string): string {
291+
return path.substring(path.lastIndexOf('/') + 1);
292+
}
293+
294+
function codesFromString(value: string): Array<number> {
295+
const codes = [];
296+
for (let i = 0; i < value.length; ++i) {
297+
codes.push(value.charCodeAt(i));
298+
}
299+
return codes;
300+
}
301+
302+
/**
303+
* String Trim function with customizable chars
304+
* @param value string to trim
305+
* @param chars chars to use to trim
306+
* @returns string trimmed
307+
*/
308+
export function trim(value: string, chars: string = ' '): string {
309+
const codes = codesFromString(chars);
310+
let start = 0;
311+
while (start < value.length && codes.includes(value.charCodeAt(start))) {
312+
++start;
313+
}
314+
let end = value.length;
315+
while (end > 0 && codes.includes(value.charCodeAt(end - 1))) {
316+
--end;
317+
}
318+
return value.substring(start, end);
319+
}
320+
321+
/**
322+
* String Trim Start function with customizable chars
323+
* @param value string to trim start
324+
* @param chars chars to use to trim start
325+
* @returns string trimmed
326+
*/
327+
export function trimStart(value: string, chars: string = ' '): string {
328+
const codes = codesFromString(chars);
329+
let i = 0;
330+
while (i < value.length && codes.includes(value.charCodeAt(i))) {
331+
++i;
332+
}
333+
return value.substring(i);
334+
}
335+
336+
/**
337+
* String Trim End function with customizable chars
338+
* @param value string to trim end
339+
* @param chars chars to use to trim end
340+
* @returns string trimmed
341+
*/
342+
export function trimEnd(value: string, chars: string = ' '): string {
343+
const codes = codesFromString(chars);
344+
let i = value.length;
345+
while (i > 0 && codes.includes(value.charCodeAt(i - 1))) {
346+
--i;
347+
}
348+
return value.substring(0, i);
349+
}

0 commit comments

Comments
 (0)