mpegts-vue3 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,237 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let vue = require("vue");
25
+ let mpegts_js = require("mpegts.js");
26
+ mpegts_js = __toESM(mpegts_js);
27
+ //#region src/components/MpegtsPlayer.vue
28
+ const _hoisted_1 = { class: "relative w-full h-full bg-black rounded-lg overflow-hidden" };
29
+ const _hoisted_2 = {
30
+ key: 0,
31
+ class: "absolute inset-0 flex flex-col items-center justify-center bg-gray-900/90"
32
+ };
33
+ const _hoisted_3 = {
34
+ key: 1,
35
+ class: "absolute inset-0 flex items-center justify-center bg-black/60"
36
+ };
37
+ const _hoisted_4 = {
38
+ key: 2,
39
+ class: "absolute inset-0 flex items-center justify-center bg-black/60"
40
+ };
41
+ const _sfc_main = /* @__PURE__ */ (0, vue.defineComponent)({
42
+ __name: "MpegtsPlayer",
43
+ props: {
44
+ url: {},
45
+ autoplay: {
46
+ type: Boolean,
47
+ default: true
48
+ },
49
+ isLive: {
50
+ type: Boolean,
51
+ default: true
52
+ },
53
+ muted: {
54
+ type: Boolean,
55
+ default: true
56
+ },
57
+ type: { default: "mse" },
58
+ cors: { type: Boolean },
59
+ withCredentials: { type: Boolean },
60
+ hasAudio: { type: Boolean },
61
+ hasVideo: { type: Boolean },
62
+ duration: {},
63
+ filesize: {},
64
+ config: { default: () => ({}) }
65
+ },
66
+ emits: ["error", "status"],
67
+ setup(__props, { expose: __expose, emit: __emit }) {
68
+ const DEFAULT_CONFIG = {
69
+ enableStashBuffer: false,
70
+ liveBufferLatencyChasing: true,
71
+ liveBufferLatencyChasingOnPaused: true,
72
+ liveBufferLatencyMaxLatency: 1.5,
73
+ liveBufferLatencyMinRemain: .3,
74
+ liveSync: true,
75
+ liveSyncMaxLatency: 1.2,
76
+ liveSyncTargetLatency: .5,
77
+ autoCleanupSourceBuffer: true,
78
+ autoCleanupMaxBackwardDuration: 30,
79
+ autoCleanupMinBackwardDuration: 10,
80
+ fixAudioTimestampGap: true
81
+ };
82
+ const props = __props;
83
+ const emit = __emit;
84
+ const videoRef = (0, vue.ref)();
85
+ const status = (0, vue.ref)("nosignal");
86
+ let player = null;
87
+ function destroyPlayer() {
88
+ if (!player) return;
89
+ status.value = "destroying";
90
+ try {
91
+ player.pause();
92
+ player.unload();
93
+ player.detachMediaElement();
94
+ player.destroy();
95
+ } catch {}
96
+ player = null;
97
+ status.value = "nosignal";
98
+ }
99
+ function play() {
100
+ if (!player) return;
101
+ videoRef.value.muted = props.muted;
102
+ const result = player.play();
103
+ if (result instanceof Promise) result.then(() => {
104
+ status.value = "playing";
105
+ emit("status", "playing");
106
+ }).catch(() => {
107
+ status.value = "stopped";
108
+ emit("status", "stopped");
109
+ });
110
+ else {
111
+ status.value = "playing";
112
+ emit("status", "playing");
113
+ }
114
+ }
115
+ function pause() {
116
+ if (!player) return;
117
+ player.pause();
118
+ status.value = "stopped";
119
+ emit("status", "stopped");
120
+ }
121
+ __expose({
122
+ play,
123
+ pause
124
+ });
125
+ function buildMediaDataSource() {
126
+ const source = {
127
+ type: props.type ?? "mse",
128
+ isLive: props.isLive,
129
+ url: props.url
130
+ };
131
+ if (props.cors !== void 0) source.cors = props.cors;
132
+ if (props.withCredentials !== void 0) source.withCredentials = props.withCredentials;
133
+ if (props.hasAudio !== void 0) source.hasAudio = props.hasAudio;
134
+ if (props.hasVideo !== void 0) source.hasVideo = props.hasVideo;
135
+ if (props.duration !== void 0) source.duration = props.duration;
136
+ if (props.filesize !== void 0) source.filesize = props.filesize;
137
+ return source;
138
+ }
139
+ function createPlayer() {
140
+ destroyPlayer();
141
+ if (!props.url || !videoRef.value) return;
142
+ if (!mpegts_js.default.isSupported()) {
143
+ status.value = "error";
144
+ emit("status", "error");
145
+ return;
146
+ }
147
+ status.value = "connecting";
148
+ emit("status", "connecting");
149
+ const mergedConfig = {
150
+ ...DEFAULT_CONFIG,
151
+ ...props.config
152
+ };
153
+ const mediaSource = buildMediaDataSource();
154
+ player = mpegts_js.default.createPlayer(mediaSource, mergedConfig);
155
+ player.attachMediaElement(videoRef.value);
156
+ player.on(mpegts_js.default.Events.ERROR, (errorType, errorDetail, errorInfo) => {
157
+ status.value = "error";
158
+ emit("status", "error");
159
+ emit("error", errorType, errorDetail, errorInfo);
160
+ });
161
+ player.load();
162
+ if (props.autoplay) {
163
+ videoRef.value.muted = props.muted;
164
+ const result = player.play();
165
+ if (result instanceof Promise) result.then(() => {
166
+ status.value = "playing";
167
+ emit("status", "playing");
168
+ }).catch(() => {
169
+ status.value = "stopped";
170
+ emit("status", "stopped");
171
+ });
172
+ else {
173
+ status.value = "playing";
174
+ emit("status", "playing");
175
+ }
176
+ }
177
+ }
178
+ (0, vue.watch)(() => props.url, (newUrl) => {
179
+ if (newUrl) createPlayer();
180
+ else {
181
+ destroyPlayer();
182
+ status.value = "nosignal";
183
+ emit("status", "nosignal");
184
+ }
185
+ });
186
+ (0, vue.watch)(() => props.config, () => {
187
+ if (props.url) createPlayer();
188
+ }, { deep: true });
189
+ (0, vue.watch)(() => [
190
+ props.type,
191
+ props.isLive,
192
+ props.cors,
193
+ props.withCredentials,
194
+ props.hasAudio,
195
+ props.hasVideo,
196
+ props.duration,
197
+ props.filesize
198
+ ], () => {
199
+ if (props.url) createPlayer();
200
+ });
201
+ (0, vue.onMounted)(() => {
202
+ if (props.url) createPlayer();
203
+ });
204
+ (0, vue.watch)(() => props.muted, (val) => {
205
+ if (videoRef.value) videoRef.value.muted = val;
206
+ });
207
+ (0, vue.onUnmounted)(() => {
208
+ destroyPlayer();
209
+ });
210
+ return (_ctx, _cache) => {
211
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1, [
212
+ (0, vue.createElementVNode)("video", {
213
+ ref_key: "videoRef",
214
+ ref: videoRef,
215
+ class: "absolute inset-0 w-full h-full object-contain",
216
+ onClick: _cache[0] || (_cache[0] = (0, vue.withModifiers)(() => {}, ["prevent"])),
217
+ onContextmenu: _cache[1] || (_cache[1] = (0, vue.withModifiers)(() => {}, ["prevent"]))
218
+ }, null, 544),
219
+ status.value === "nosignal" || !__props.url ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2, [..._cache[2] || (_cache[2] = [(0, vue.createStaticVNode)("<div class=\"mb-3 flex items-center gap-2 text-gray-400\"><svg class=\"size-10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\"><path d=\"m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path><path d=\"M18 12 6 12M18 8 6 8M18 16l-12 0\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg></div><span class=\"text-sm font-medium text-gray-400 tracking-wider uppercase\"> No Signal </span>", 2)])])) : (0, vue.createCommentVNode)("v-if", true),
220
+ status.value === "connecting" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_3, [..._cache[3] || (_cache[3] = [(0, vue.createElementVNode)("div", { class: "flex flex-col items-center gap-3" }, [(0, vue.createElementVNode)("div", { class: "size-8 rounded-full border-2 border-blue-500 border-t-transparent animate-spin" }), (0, vue.createElementVNode)("span", { class: "text-sm text-gray-300" }, "Connecting...")], -1)])])) : (0, vue.createCommentVNode)("v-if", true),
221
+ status.value === "error" && __props.url ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_4, [..._cache[4] || (_cache[4] = [(0, vue.createElementVNode)("div", { class: "flex flex-col items-center gap-2" }, [(0, vue.createElementVNode)("svg", {
222
+ class: "size-8 text-red-400",
223
+ fill: "none",
224
+ stroke: "currentColor",
225
+ "stroke-width": "1.5",
226
+ viewBox: "0 0 24 24"
227
+ }, [(0, vue.createElementVNode)("path", {
228
+ d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z",
229
+ "stroke-linecap": "round",
230
+ "stroke-linejoin": "round"
231
+ })]), (0, vue.createElementVNode)("span", { class: "text-sm text-red-400" }, "Connection Failed")], -1)])])) : (0, vue.createCommentVNode)("v-if", true)
232
+ ]);
233
+ };
234
+ }
235
+ });
236
+ //#endregion
237
+ exports.MpegtsPlayer = _sfc_main;
@@ -0,0 +1,44 @@
1
+ import * as vue0 from "vue";
2
+ import Mpegts from "mpegts.js";
3
+
4
+ //#region src/types.d.ts
5
+ type MediaDataSource = Mpegts.MediaDataSource;
6
+ type MediaSegment = Mpegts.MediaSegment;
7
+ type MpegtsConfig = Mpegts.Config;
8
+ type PlayerStatus = 'connecting' | 'destroying' | 'error' | 'nosignal' | 'playing' | 'stopped';
9
+ //#endregion
10
+ //#region src/components/MpegtsPlayer.vue.d.ts
11
+ interface Props {
12
+ url: string;
13
+ autoplay?: boolean;
14
+ isLive?: boolean;
15
+ muted?: boolean;
16
+ type?: string;
17
+ cors?: boolean;
18
+ withCredentials?: boolean;
19
+ hasAudio?: boolean;
20
+ hasVideo?: boolean;
21
+ duration?: number;
22
+ filesize?: number;
23
+ config?: Partial<MpegtsConfig>;
24
+ }
25
+ declare function play(): void;
26
+ declare function pause(): void;
27
+ declare const _default: vue0.DefineComponent<Props, {
28
+ play: typeof play;
29
+ pause: typeof pause;
30
+ }, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {
31
+ error: (errorType: string, errorDetail: string, errorInfo: any) => any;
32
+ status: (status: PlayerStatus) => any;
33
+ }, string, vue0.PublicProps, Readonly<Props> & Readonly<{
34
+ onError?: ((errorType: string, errorDetail: string, errorInfo: any) => any) | undefined;
35
+ onStatus?: ((status: PlayerStatus) => any) | undefined;
36
+ }>, {
37
+ autoplay: boolean;
38
+ isLive: boolean;
39
+ muted: boolean;
40
+ type: string;
41
+ config: Partial<MpegtsConfig>;
42
+ }, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
43
+ //#endregion
44
+ export { type MediaDataSource, type MediaSegment, type MpegtsConfig, _default as MpegtsPlayer, type PlayerStatus };
@@ -0,0 +1,44 @@
1
+ import * as vue0 from "vue";
2
+ import Mpegts from "mpegts.js";
3
+
4
+ //#region src/types.d.ts
5
+ type MediaDataSource = Mpegts.MediaDataSource;
6
+ type MediaSegment = Mpegts.MediaSegment;
7
+ type MpegtsConfig = Mpegts.Config;
8
+ type PlayerStatus = 'connecting' | 'destroying' | 'error' | 'nosignal' | 'playing' | 'stopped';
9
+ //#endregion
10
+ //#region src/components/MpegtsPlayer.vue.d.ts
11
+ interface Props {
12
+ url: string;
13
+ autoplay?: boolean;
14
+ isLive?: boolean;
15
+ muted?: boolean;
16
+ type?: string;
17
+ cors?: boolean;
18
+ withCredentials?: boolean;
19
+ hasAudio?: boolean;
20
+ hasVideo?: boolean;
21
+ duration?: number;
22
+ filesize?: number;
23
+ config?: Partial<MpegtsConfig>;
24
+ }
25
+ declare function play(): void;
26
+ declare function pause(): void;
27
+ declare const _default: vue0.DefineComponent<Props, {
28
+ play: typeof play;
29
+ pause: typeof pause;
30
+ }, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {
31
+ error: (errorType: string, errorDetail: string, errorInfo: any) => any;
32
+ status: (status: PlayerStatus) => any;
33
+ }, string, vue0.PublicProps, Readonly<Props> & Readonly<{
34
+ onError?: ((errorType: string, errorDetail: string, errorInfo: any) => any) | undefined;
35
+ onStatus?: ((status: PlayerStatus) => any) | undefined;
36
+ }>, {
37
+ autoplay: boolean;
38
+ isLive: boolean;
39
+ muted: boolean;
40
+ type: string;
41
+ config: Partial<MpegtsConfig>;
42
+ }, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
43
+ //#endregion
44
+ export { type MediaDataSource, type MediaSegment, type MpegtsConfig, _default as MpegtsPlayer, type PlayerStatus };
package/dist/index.js ADDED
@@ -0,0 +1,213 @@
1
+ import { createCommentVNode, createElementBlock, createElementVNode, createStaticVNode, defineComponent, onMounted, onUnmounted, openBlock, ref, watch, withModifiers } from "vue";
2
+ import Mpegts from "mpegts.js";
3
+ //#region src/components/MpegtsPlayer.vue
4
+ const _hoisted_1 = { class: "relative w-full h-full bg-black rounded-lg overflow-hidden" };
5
+ const _hoisted_2 = {
6
+ key: 0,
7
+ class: "absolute inset-0 flex flex-col items-center justify-center bg-gray-900/90"
8
+ };
9
+ const _hoisted_3 = {
10
+ key: 1,
11
+ class: "absolute inset-0 flex items-center justify-center bg-black/60"
12
+ };
13
+ const _hoisted_4 = {
14
+ key: 2,
15
+ class: "absolute inset-0 flex items-center justify-center bg-black/60"
16
+ };
17
+ const _sfc_main = /* @__PURE__ */ defineComponent({
18
+ __name: "MpegtsPlayer",
19
+ props: {
20
+ url: {},
21
+ autoplay: {
22
+ type: Boolean,
23
+ default: true
24
+ },
25
+ isLive: {
26
+ type: Boolean,
27
+ default: true
28
+ },
29
+ muted: {
30
+ type: Boolean,
31
+ default: true
32
+ },
33
+ type: { default: "mse" },
34
+ cors: { type: Boolean },
35
+ withCredentials: { type: Boolean },
36
+ hasAudio: { type: Boolean },
37
+ hasVideo: { type: Boolean },
38
+ duration: {},
39
+ filesize: {},
40
+ config: { default: () => ({}) }
41
+ },
42
+ emits: ["error", "status"],
43
+ setup(__props, { expose: __expose, emit: __emit }) {
44
+ const DEFAULT_CONFIG = {
45
+ enableStashBuffer: false,
46
+ liveBufferLatencyChasing: true,
47
+ liveBufferLatencyChasingOnPaused: true,
48
+ liveBufferLatencyMaxLatency: 1.5,
49
+ liveBufferLatencyMinRemain: .3,
50
+ liveSync: true,
51
+ liveSyncMaxLatency: 1.2,
52
+ liveSyncTargetLatency: .5,
53
+ autoCleanupSourceBuffer: true,
54
+ autoCleanupMaxBackwardDuration: 30,
55
+ autoCleanupMinBackwardDuration: 10,
56
+ fixAudioTimestampGap: true
57
+ };
58
+ const props = __props;
59
+ const emit = __emit;
60
+ const videoRef = ref();
61
+ const status = ref("nosignal");
62
+ let player = null;
63
+ function destroyPlayer() {
64
+ if (!player) return;
65
+ status.value = "destroying";
66
+ try {
67
+ player.pause();
68
+ player.unload();
69
+ player.detachMediaElement();
70
+ player.destroy();
71
+ } catch {}
72
+ player = null;
73
+ status.value = "nosignal";
74
+ }
75
+ function play() {
76
+ if (!player) return;
77
+ videoRef.value.muted = props.muted;
78
+ const result = player.play();
79
+ if (result instanceof Promise) result.then(() => {
80
+ status.value = "playing";
81
+ emit("status", "playing");
82
+ }).catch(() => {
83
+ status.value = "stopped";
84
+ emit("status", "stopped");
85
+ });
86
+ else {
87
+ status.value = "playing";
88
+ emit("status", "playing");
89
+ }
90
+ }
91
+ function pause() {
92
+ if (!player) return;
93
+ player.pause();
94
+ status.value = "stopped";
95
+ emit("status", "stopped");
96
+ }
97
+ __expose({
98
+ play,
99
+ pause
100
+ });
101
+ function buildMediaDataSource() {
102
+ const source = {
103
+ type: props.type ?? "mse",
104
+ isLive: props.isLive,
105
+ url: props.url
106
+ };
107
+ if (props.cors !== void 0) source.cors = props.cors;
108
+ if (props.withCredentials !== void 0) source.withCredentials = props.withCredentials;
109
+ if (props.hasAudio !== void 0) source.hasAudio = props.hasAudio;
110
+ if (props.hasVideo !== void 0) source.hasVideo = props.hasVideo;
111
+ if (props.duration !== void 0) source.duration = props.duration;
112
+ if (props.filesize !== void 0) source.filesize = props.filesize;
113
+ return source;
114
+ }
115
+ function createPlayer() {
116
+ destroyPlayer();
117
+ if (!props.url || !videoRef.value) return;
118
+ if (!Mpegts.isSupported()) {
119
+ status.value = "error";
120
+ emit("status", "error");
121
+ return;
122
+ }
123
+ status.value = "connecting";
124
+ emit("status", "connecting");
125
+ const mergedConfig = {
126
+ ...DEFAULT_CONFIG,
127
+ ...props.config
128
+ };
129
+ const mediaSource = buildMediaDataSource();
130
+ player = Mpegts.createPlayer(mediaSource, mergedConfig);
131
+ player.attachMediaElement(videoRef.value);
132
+ player.on(Mpegts.Events.ERROR, (errorType, errorDetail, errorInfo) => {
133
+ status.value = "error";
134
+ emit("status", "error");
135
+ emit("error", errorType, errorDetail, errorInfo);
136
+ });
137
+ player.load();
138
+ if (props.autoplay) {
139
+ videoRef.value.muted = props.muted;
140
+ const result = player.play();
141
+ if (result instanceof Promise) result.then(() => {
142
+ status.value = "playing";
143
+ emit("status", "playing");
144
+ }).catch(() => {
145
+ status.value = "stopped";
146
+ emit("status", "stopped");
147
+ });
148
+ else {
149
+ status.value = "playing";
150
+ emit("status", "playing");
151
+ }
152
+ }
153
+ }
154
+ watch(() => props.url, (newUrl) => {
155
+ if (newUrl) createPlayer();
156
+ else {
157
+ destroyPlayer();
158
+ status.value = "nosignal";
159
+ emit("status", "nosignal");
160
+ }
161
+ });
162
+ watch(() => props.config, () => {
163
+ if (props.url) createPlayer();
164
+ }, { deep: true });
165
+ watch(() => [
166
+ props.type,
167
+ props.isLive,
168
+ props.cors,
169
+ props.withCredentials,
170
+ props.hasAudio,
171
+ props.hasVideo,
172
+ props.duration,
173
+ props.filesize
174
+ ], () => {
175
+ if (props.url) createPlayer();
176
+ });
177
+ onMounted(() => {
178
+ if (props.url) createPlayer();
179
+ });
180
+ watch(() => props.muted, (val) => {
181
+ if (videoRef.value) videoRef.value.muted = val;
182
+ });
183
+ onUnmounted(() => {
184
+ destroyPlayer();
185
+ });
186
+ return (_ctx, _cache) => {
187
+ return openBlock(), createElementBlock("div", _hoisted_1, [
188
+ createElementVNode("video", {
189
+ ref_key: "videoRef",
190
+ ref: videoRef,
191
+ class: "absolute inset-0 w-full h-full object-contain",
192
+ onClick: _cache[0] || (_cache[0] = withModifiers(() => {}, ["prevent"])),
193
+ onContextmenu: _cache[1] || (_cache[1] = withModifiers(() => {}, ["prevent"]))
194
+ }, null, 544),
195
+ status.value === "nosignal" || !__props.url ? (openBlock(), createElementBlock("div", _hoisted_2, [..._cache[2] || (_cache[2] = [createStaticVNode("<div class=\"mb-3 flex items-center gap-2 text-gray-400\"><svg class=\"size-10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\"><path d=\"m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path><path d=\"M18 12 6 12M18 8 6 8M18 16l-12 0\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg></div><span class=\"text-sm font-medium text-gray-400 tracking-wider uppercase\"> No Signal </span>", 2)])])) : createCommentVNode("v-if", true),
196
+ status.value === "connecting" ? (openBlock(), createElementBlock("div", _hoisted_3, [..._cache[3] || (_cache[3] = [createElementVNode("div", { class: "flex flex-col items-center gap-3" }, [createElementVNode("div", { class: "size-8 rounded-full border-2 border-blue-500 border-t-transparent animate-spin" }), createElementVNode("span", { class: "text-sm text-gray-300" }, "Connecting...")], -1)])])) : createCommentVNode("v-if", true),
197
+ status.value === "error" && __props.url ? (openBlock(), createElementBlock("div", _hoisted_4, [..._cache[4] || (_cache[4] = [createElementVNode("div", { class: "flex flex-col items-center gap-2" }, [createElementVNode("svg", {
198
+ class: "size-8 text-red-400",
199
+ fill: "none",
200
+ stroke: "currentColor",
201
+ "stroke-width": "1.5",
202
+ viewBox: "0 0 24 24"
203
+ }, [createElementVNode("path", {
204
+ d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z",
205
+ "stroke-linecap": "round",
206
+ "stroke-linejoin": "round"
207
+ })]), createElementVNode("span", { class: "text-sm text-red-400" }, "Connection Failed")], -1)])])) : createCommentVNode("v-if", true)
208
+ ]);
209
+ };
210
+ }
211
+ });
212
+ //#endregion
213
+ export { _sfc_main as MpegtsPlayer };
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "mpegts-vue3",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Vue 3 component for mpegts.js video streaming player",
6
+ "keywords": [
7
+ "vue",
8
+ "vue3",
9
+ "mpegts",
10
+ "flv",
11
+ "live-streaming",
12
+ "player"
13
+ ],
14
+ "license": "MIT",
15
+ "author": "",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/huangzida/mpegts-vue3"
19
+ },
20
+ "main": "./dist/index.cjs",
21
+ "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "import": {
26
+ "types": "./dist/index.d.ts",
27
+ "default": "./dist/index.js"
28
+ },
29
+ "require": {
30
+ "types": "./dist/index.d.cts",
31
+ "default": "./dist/index.cjs"
32
+ }
33
+ }
34
+ },
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "sideEffects": false,
39
+ "scripts": {
40
+ "build": "tsdown && node -e \"const fs=require('fs'),d='dist';fs.readdirSync(d).filter(f=>f.startsWith('index-')&&f.endsWith('.d.ts')).forEach(f=>fs.renameSync(d+'/'+f,d+'/index.d.ts'));fs.readdirSync(d).filter(f=>f.startsWith('index-')&&f.endsWith('.d.cts')).forEach(f=>fs.renameSync(d+'/'+f,d+'/index.d.cts'))\"",
41
+ "dev": "tsdown --watch"
42
+ },
43
+ "peerDependencies": {
44
+ "mpegts.js": "^1.8.0",
45
+ "vue": "^3.4.0"
46
+ },
47
+ "devDependencies": {
48
+ "mpegts.js": "^1.8.0",
49
+ "tsdown": "^0.12.0",
50
+ "typescript": "^5.8.0",
51
+ "unplugin-vue": "^7.1.1",
52
+ "vue": "^3.5.0",
53
+ "vue-tsc": "^2.2.0"
54
+ }
55
+ }