Skip to content

Commit

Permalink
Feat: proxy movie
Browse files Browse the repository at this point in the history
  • Loading branch information
zijiren233 committed Nov 7, 2023
1 parent 93dc2a1 commit 1bf5105
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 66 deletions.
119 changes: 66 additions & 53 deletions src/components/MoviePush.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { ElNotification } from "element-plus";
import type { BaseMovieInfo } from "@/proto/message";
import { BaseMovieInfo, VendorInfo, BilibiliVendorInfo } from "@/proto/message";
import { strLengthLimit } from "@/utils/utils";
import { pushMovieApi } from "@/services/apis/movie";
import customHeaders from "@/components/dialogs/customHeaders.vue";
Expand All @@ -18,26 +18,20 @@ const roomID = useRouteParams("roomId");
const roomToken = localStorage.getItem(`room-${roomID.value}-token`) ?? "";
// 新影片信息
let newMovieInfo = ref<BaseMovieInfo>({
url: "",
name: "",
live: false,
proxy: false,
rtmpSource: false,
type: "",
headers: {},
vendorInfo: undefined
});
let newMovieInfo = ref<BaseMovieInfo>(BaseMovieInfo.create());
enum pushType {
MOVIE = 0,
LIVE,
PROXY_LIVE,
RTMP_SOURCE,
BILIBILI
}
interface movieTypeRecord {
name: string;
comment: string;
showProxy: boolean;
defaultType: string;
allowedTypes: Array<{ name: string; value: string }>;
}
Expand All @@ -47,6 +41,8 @@ const movieTypeRecords: Map<pushType, movieTypeRecord> = new Map([
pushType.MOVIE,
{
name: "视频直链",
comment: "",
showProxy: true,
defaultType: "",
allowedTypes: [
{
Expand Down Expand Up @@ -80,6 +76,8 @@ const movieTypeRecords: Map<pushType, movieTypeRecord> = new Map([
pushType.LIVE,
{
name: "直播流",
comment: "",
showProxy: false,
defaultType: "",
allowedTypes: [
{
Expand All @@ -93,18 +91,26 @@ const movieTypeRecords: Map<pushType, movieTypeRecord> = new Map([
{
name: "m3u8",
value: "m3u8"
},
{
name: "ts",
value: "mpegts"
}
]
}
],
[
pushType.PROXY_LIVE,
{
name: "代理直播流",
comment: "仅支持rtmp和flv代理",
showProxy: false,
defaultType: "",
allowedTypes: []
}
],
[
pushType.RTMP_SOURCE,
{
name: "创建直播",
comment: "用户可自行推流",
showProxy: false,
defaultType: "flv",
allowedTypes: [
{
Expand All @@ -122,6 +128,8 @@ const movieTypeRecords: Map<pushType, movieTypeRecord> = new Map([
pushType.BILIBILI,
{
name: "哔哩哔哩",
comment: "解析Bilibili视频",
showProxy: false,
defaultType: "",
allowedTypes: []
}
Expand All @@ -133,45 +141,40 @@ const selectedMovieType = ref(pushType.MOVIE);
const selectPushType = () => {
switch (selectedMovieType.value) {
case pushType.MOVIE:
newMovieInfo.value.live = newMovieInfo.value.proxy = newMovieInfo.value.rtmpSource = false;
newMovieInfo.value.vendorInfo = undefined;
newMovieInfo.value = BaseMovieInfo.create({
url: newMovieInfo.value.url,
name: newMovieInfo.value.name
});
break;
case pushType.LIVE:
newMovieInfo.value.live = true;
newMovieInfo.value.proxy = newMovieInfo.value.rtmpSource = false;
newMovieInfo.value.vendorInfo = undefined;
newMovieInfo.value = BaseMovieInfo.create({
url: newMovieInfo.value.url,
name: newMovieInfo.value.name,
live: true
});
break;
case pushType.RTMP_SOURCE:
newMovieInfo.value.proxy = false;
newMovieInfo.value.live = newMovieInfo.value.rtmpSource = true;
newMovieInfo.value.headers = {};
newMovieInfo.value.vendorInfo = undefined;
newMovieInfo.value = BaseMovieInfo.create({
url: newMovieInfo.value.url,
name: newMovieInfo.value.name,
live: true,
rtmpSource: true
});
break;
case pushType.BILIBILI:
newMovieInfo.value.live = newMovieInfo.value.proxy = newMovieInfo.value.rtmpSource = false;
newMovieInfo.value.headers = {};
newMovieInfo.value.vendorInfo = {
vendor: "bilibili",
shared: true,
bilibili: {
bvid: "",
cid: NaN,
epid: NaN,
quality: NaN
}
};
newMovieInfo.value = BaseMovieInfo.create({
url: newMovieInfo.value.url,
name: newMovieInfo.value.name,
vendorInfo: VendorInfo.create({
vendor: "bilibili",
shared: true,
bilibili: BilibiliVendorInfo.create({})
})
});
break;
}
newMovieInfo.value.type = movieTypeRecords.get(selectedMovieType.value)!.defaultType;
};
const selectMovieType = () => {
newMovieInfo.value.type =
movieTypeRecords
.get(selectedMovieType.value)
?.allowedTypes.find((v) => v.value === newMovieInfo.value.type)?.value ||
movieTypeRecords.get(selectedMovieType.value)!.defaultType;
newMovieInfo.value.type = movieTypeRecords.get(selectedMovieType.value)?.defaultType || "";
};
const stringHeader = ref(JSON.stringify(newMovieInfo.value.headers));
Expand Down Expand Up @@ -273,22 +276,32 @@ onMounted(() => {});
<el-collapse @change="" class="bg-transparent" style="background: #aaa0 !important">
<el-collapse-item>
<template #title><div class="text-base font-medium">高级选项</div></template>
<div class="more-option-list">
<div
class="more-option-list"
v-if="movieTypeRecords.get(selectedMovieType)?.allowedTypes.length != 0"
>
<span class="text-sm min-w-fit"> 视频类型: </span>

<select
@change="selectMovieType"
v-model="newMovieInfo.type"
class="bg-transparent p-0 text-base w-full h-5"
>
<select v-model="newMovieInfo.type" class="bg-transparent p-0 text-base w-full h-5">
<option
v-for="allowedType in movieTypeRecords.get(selectedMovieType)?.allowedTypes"
v-for="allowedType in movieTypeRecords.get(selectedMovieType)!.allowedTypes"
:value="allowedType.value"
>
{{ allowedType.name }}
</option>
</select>
</div>
<Transition name="fade">
<div class="more-option-list" v-if="movieTypeRecords.get(selectedMovieType)?.showProxy">
<label
>代理:
<input
type="checkbox"
v-model="newMovieInfo.proxy"
:value="true"
:unchecked-value="false"
/></label>
</div>
</Transition>
<Transition name="fade">
<div
class="more-option-list cursor-pointer"
Expand Down
3 changes: 2 additions & 1 deletion src/components/Player.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ let art: Artplayer;
interface options {
url: string;
isLive: boolean;
type: string;
type?: string;
headers: { [key: string]: string };
plugins: ((art: Artplayer) => unknown)[];
}
Expand Down Expand Up @@ -186,6 +186,7 @@ const playerOption = computed<Option>(() => {
autoOrientation: true, // 移动端的网页全屏时,根据视频尺寸和视口尺寸,旋转播放器
airplay: false, // 隔空播放
...Props.options,
type: Props.options.type,
customType: {
flv: playFlv,
m3u8: playM3u8,
Expand Down
21 changes: 9 additions & 12 deletions src/views/Cinema.vue
Original file line number Diff line number Diff line change
Expand Up @@ -614,13 +614,6 @@ function getPlayerInstance(art: Artplayer) {
resetChatAreaHeight();
}
const parseVideoType = (movie: MovieInfo) => {
if (movie.base!.type) {
return movie.base!.type;
}
return getFileExtension(movie.base!.url);
};
// 设置聊天框高度
const resetChatAreaHeight = () => {
const h = playArea.value ? playArea : noPlayArea;
Expand All @@ -645,12 +638,15 @@ const danmukuPlugin = artplayerPluginDanmuku({
});
const playerUrl = computed(() => {
if (room.currentMovie.base?.rtmpSource) {
if (
room.currentMovie.base?.rtmpSource ||
(room.currentMovie.base?.live && room.currentMovie.base?.proxy)
) {
switch (room.currentMovie.base!.type) {
case "m3u8":
return `${window.location.origin}/api/movie/live/${room.currentMovie.id}.m3u8`;
default:
case "flv":
return `${window.location.origin}/api/movie/live/${room.currentMovie.id}.flv`;
default:
return `${window.location.origin}/api/movie/live/${room.currentMovie.id}.m3u8`;
}
} else if (room.currentMovie.base?.proxy) {
return `${window.location.origin}/api/movie/proxy/${roomID.value}/${room.currentMovie.id}`;
Expand All @@ -662,8 +658,8 @@ const playerUrl = computed(() => {
const playerOption = computed(() => {
let option = {
url: playerUrl.value,
type: room.currentMovie.base?.type || getFileExtension(playerUrl.value),
isLive: room.currentMovie.base!.live,
type: parseVideoType(room.currentMovie),
headers: room.currentMovie.base!.headers,
plugins: [danmukuPlugin, syncPlugin.plugin]
};
Expand All @@ -673,6 +669,7 @@ const playerOption = computed(() => {
Authorization: roomToken
};
}
return option;
});
Expand Down

0 comments on commit 1bf5105

Please sign in to comment.