fix: 修复MSD上传功能和多项构建优化

- 修复MSD上传中prefix参数编码问题
- 移除重复的uploading-sub元素定义
- 优化Python依赖库清理和缓存管理
- 改进Rockchip硬件加速库构建流程
- 增强国际化语言检测和设置
- 修正ttyd下载地址和系统服务配置
This commit is contained in:
mofeng-git 2025-08-25 20:14:50 +08:00
parent ccdfd52b75
commit ecc27c2be7
9 changed files with 65 additions and 40 deletions

View File

@ -4,14 +4,17 @@ FROM python:3.11.11-slim-bookworm
LABEL maintainer="mofeng654321@hotmail.com" LABEL maintainer="mofeng654321@hotmail.com"
ARG TARGETARCH
COPY --from=builder /tmp/lib/* /tmp/lib/ COPY --from=builder /tmp/lib/* /tmp/lib/
COPY --from=builder /tmp/ustreamer/ustreamer /tmp/ustreamer/ustreamer-dump /usr/bin/janus /usr/bin/ COPY --from=builder /tmp/ustreamer/ustreamer /tmp/ustreamer/ustreamer-dump /usr/bin/janus /usr/bin/
COPY --from=builder /tmp/wheel/*.whl /tmp/wheel/ COPY --from=builder /tmp/wheel/*.whl /tmp/wheel/
COPY --from=builder /tmp/ustreamer/libjanus_ustreamer.so /usr/lib/ustreamer/janus/ COPY --from=builder /tmp/ustreamer/libjanus_ustreamer.so /usr/lib/ustreamer/janus/
COPY --from=builder /usr/lib/janus/transports/* /usr/lib/janus/transports/ COPY --from=builder /usr/lib/janus/transports/* /usr/lib/janus/transports/
COPY --from=builder /opt/usr/ /usr/ COPY --from=builder /tmp/arm64-libs.tar.gz /tmp/
RUN if [ ${TARGETARCH} = arm64 ]; then \
ARG TARGETARCH cd / && tar -xzf /tmp/arm64-libs.tar.gz && rm -f /tmp/arm64-libs.tar.gz; \
fi
ENV PYTHONDONTWRITEBYTECODE=1 \ ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \ PYTHONUNBUFFERED=1 \

View File

@ -103,12 +103,18 @@ RUN --security=insecure pip config set global.index-url https://pypi.tuna.tsingh
pycparser pyelftools pyghmi pygments pyparsing pyotp qrcode requests \ pycparser pyelftools pyghmi pygments pyparsing pyotp qrcode requests \
semantic-version setproctitle six spidev tabulate urllib3 wrapt xlib \ semantic-version setproctitle six spidev tabulate urllib3 wrapt xlib \
yarl pyserial pyyaml zstandard supervisor pyfatfs pyserial python-periphery \ yarl pyserial pyyaml zstandard supervisor pyfatfs pyserial python-periphery \
python-ldap python-pam pyrad pyudev pyusb luma.oled pyserial-asyncio python-ldap python-pam pyrad pyudev pyusb luma.oled pyserial-asyncio \
&& rm -rf /root/.cache/pip/* /tmp/pip-* \
&& if [ ${TARGETARCH} = arm ]; then \
umount /root/.cargo 2>/dev/null || true \
&& rm -rf /root/.cargo /root/rustup-init.sh; \
fi
# 编译 python vedev库 # 编译 python evdev库
RUN git clone --depth=1 https://github.com/gvalkov/python-evdev.git /tmp/python-evdev \ RUN git clone --depth=1 https://github.com/gvalkov/python-evdev.git /tmp/python-evdev \
&& cd /tmp/python-evdev \ && cd /tmp/python-evdev \
&& python3 setup.py bdist_wheel --dist-dir /tmp/wheel/ && python3 setup.py bdist_wheel --dist-dir /tmp/wheel/ \
&& rm -rf /tmp/python-evdev
# 编译安装 libnice、libsrtp、libwebsockets 和 janus-gateway # 编译安装 libnice、libsrtp、libwebsockets 和 janus-gateway
RUN git clone --depth=1 https://gitlab.freedesktop.org/libnice/libnice /tmp/libnice \ RUN git clone --depth=1 https://gitlab.freedesktop.org/libnice/libnice /tmp/libnice \
@ -120,14 +126,14 @@ RUN git clone --depth=1 https://gitlab.freedesktop.org/libnice/libnice /tmp/libn
&& tar xf libsrtp-2.2.0.tar.gz \ && tar xf libsrtp-2.2.0.tar.gz \
&& cd libsrtp-2.2.0 \ && cd libsrtp-2.2.0 \
&& ./configure --prefix=/usr --enable-openssl \ && ./configure --prefix=/usr --enable-openssl \
&& make shared_library -j && make install \ && make shared_library -j$(nproc) && make install \
&& cd /tmp \ && cd /tmp \
&& rm -rf /tmp/libsrtp* \ && rm -rf /tmp/libsrtp* \
&& git clone --depth=1 https://github.com/warmcat/libwebsockets /tmp/libwebsockets \ && git clone --depth=1 https://github.com/warmcat/libwebsockets /tmp/libwebsockets \
&& cd /tmp/libwebsockets \ && cd /tmp/libwebsockets \
&& mkdir build && cd build \ && mkdir build && cd build \
&& cmake -DLWS_MAX_SMP=1 -DLWS_WITHOUT_EXTENSIONS=0 -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_C_FLAGS="-fpic" .. \ && cmake -DLWS_MAX_SMP=1 -DLWS_WITHOUT_EXTENSIONS=0 -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_C_FLAGS="-fpic" .. \
&& make -j && make install \ && make -j$(nproc) && make install \
&& cd /tmp \ && cd /tmp \
&& rm -rf /tmp/libwebsockets \ && rm -rf /tmp/libwebsockets \
&& git clone --depth=1 https://github.com/meetecho/janus-gateway.git /tmp/janus-gateway \ && git clone --depth=1 https://github.com/meetecho/janus-gateway.git /tmp/janus-gateway \
@ -136,29 +142,35 @@ RUN git clone --depth=1 https://gitlab.freedesktop.org/libnice/libnice /tmp/libn
&& ./configure --enable-static --enable-websockets --enable-plugin-audiobridge \ && ./configure --enable-static --enable-websockets --enable-plugin-audiobridge \
--disable-data-channels --disable-rabbitmq --disable-mqtt --disable-all-plugins \ --disable-data-channels --disable-rabbitmq --disable-mqtt --disable-all-plugins \
--disable-all-loggers --prefix=/usr \ --disable-all-loggers --prefix=/usr \
&& make -j && make install \ && make -j$(nproc) && make install \
&& cd /tmp \ && cd /tmp \
&& rm -rf /tmp/janus-gateway && rm -rf /tmp/janus-gateway
# 编译 Rockchip MPP、RGA 和 FFmpeg仅 arm64 # 编译 Rockchip MPP、RGA 和 FFmpeg仅 arm64
RUN if [ ${TARGETARCH} = arm64 ]; then \ RUN if [ ${TARGETARCH} = arm64 ]; then \
git clone --depth=1 https://github.com/rockchip-linux/mpp.git /tmp/mpp \ git clone -b jellyfin-mpp --depth=1 https://github.com/nyanmisaka/mpp.git /tmp/rkmpp \
&& cd /tmp/mpp \ && mkdir -p /tmp/rkmpp/rkmpp_build && cd /tmp/rkmpp/rkmpp_build \
&& cmake -DRKPLATFORM=ON -DCMAKE_INSTALL_PREFIX=/usr . \ && cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DBUILD_TEST=OFF .. \
&& make -j$(nproc) \ && make -j$(nproc) \
&& make install \ && make install \
&& make install DESTDIR=/opt \ && make install DESTDIR=/opt \
&& git clone --depth=1 -b 1.9.1 https://github.com/airockchip/librga /tmp/librga \ && git clone -b jellyfin-rga --depth=1 https://github.com/nyanmisaka/rk-mirrors.git /tmp/rkrga \
&& cd /tmp/librga \ && cd /tmp/ \
&& meson setup --prefix=/usr rkrga_build \ && meson setup rkrga rkrga_build --prefix=/usr --libdir=lib --buildtype=release -Dcpp_args=-fpermissive -Dlibdrm=false -Dlibrga_demo=false \
&& meson configure rkrga_build > /dev/null \
&& ninja -C rkrga_build install \ && ninja -C rkrga_build install \
&& DESTDIR=/opt ninja -C rkrga_build install \ && DESTDIR=/opt ninja -C rkrga_build install \
&& git clone --depth=1 https://github.com/nyanmisaka/ffmpeg-rockchip.git /tmp/ffmpeg-rockchip \ && git clone https://github.com/nyanmisaka/ffmpeg-rockchip.git /tmp/ffmpeg-rockchip \
&& cd /tmp/ffmpeg-rockchip \ && cd /tmp/ffmpeg-rockchip \
&& ./configure --prefix=/usr --enable-gpl --enable-version3 --enable-libdrm --enable-rkmpp --enable-rkrga --enable-alsa --enable-libv4l2 --enable-libx264 --enable-v4l2-m2m --disable-programs \ && ./configure --prefix=/usr --enable-gpl --enable-version3 --enable-libdrm --enable-rkmpp --enable-rkrga \
--enable-libv4l2 --enable-libx264 --enable-shared --disable-programs \
--disable-doc --disable-htmlpages --disable-manpages --disable-network --disable-protocols \
--disable-decoders --disable-debug --disable-alsa \
&& make -j$(nproc) \ && make -j$(nproc) \
&& make install \ && make install \
&& make install DESTDIR=/opt; \ && make install DESTDIR=/opt \
&& cd /opt && tar -czf /tmp/arm64-libs.tar.gz usr/ \
&& rm -rf /tmp/rkmpp /tmp/rkrga /tmp/ffmpeg-rockchip /opt/usr; \
fi fi
# 编译 ustreamer # 编译 ustreamer
@ -166,7 +178,7 @@ RUN echo "Building ustreamer with timestamp cache bust" \
&& sed --in-place --expression 's|^#include "refcount.h"$|#include "../refcount.h"|g' /usr/include/janus/plugins/plugin.h \ && sed --in-place --expression 's|^#include "refcount.h"$|#include "../refcount.h"|g' /usr/include/janus/plugins/plugin.h \
&& TIMESTAMP=$(date +%s%N) \ && TIMESTAMP=$(date +%s%N) \
&& git clone --depth=1 https://github.com/mofeng-git/ustreamer /tmp/ustreamer-${TIMESTAMP} \ && git clone --depth=1 https://github.com/mofeng-git/ustreamer /tmp/ustreamer-${TIMESTAMP} \
&& make -j WITH_PYTHON=1 WITH_JANUS=1 WITH_FFMPEG=1 -C /tmp/ustreamer-${TIMESTAMP} \ && make -j$(nproc) WITH_PYTHON=1 WITH_JANUS=1 WITH_FFMPEG=1 -C /tmp/ustreamer-${TIMESTAMP} \
&& /tmp/ustreamer-${TIMESTAMP}/ustreamer -v \ && /tmp/ustreamer-${TIMESTAMP}/ustreamer -v \
&& cp /tmp/ustreamer-${TIMESTAMP}/python/dist/*.whl /tmp/wheel/ \ && cp /tmp/ustreamer-${TIMESTAMP}/python/dist/*.whl /tmp/wheel/ \
&& mv /tmp/ustreamer-${TIMESTAMP} /tmp/ustreamer && mv /tmp/ustreamer-${TIMESTAMP} /tmp/ustreamer

View File

@ -180,9 +180,8 @@ configure_system() {
cat /One-KVM/configs/os/udev/v2-hdmiusb-rpi4.rules > /etc/udev/rules.d/99-kvmd.rules && \\ cat /One-KVM/configs/os/udev/v2-hdmiusb-rpi4.rules > /etc/udev/rules.d/99-kvmd.rules && \\
echo 'libcomposite' >> /etc/modules && \\ echo 'libcomposite' >> /etc/modules && \\
mv /usr/local/bin/kvmd* /usr/bin/ || echo '信息:/usr/local/bin/kvmd* 未找到或移动失败,可能已在/usr/bin' && \\ mv /usr/local/bin/kvmd* /usr/bin/ || echo '信息:/usr/local/bin/kvmd* 未找到或移动失败,可能已在/usr/bin' && \\
cp /One-KVM/configs/os/services/* /etc/systemd/system/ && \\ cp -r /One-KVM/configs/os/services/* /etc/systemd/system/ && \\
cp /One-KVM/configs/os/tmpfiles.conf /usr/lib/tmpfiles.d/ && \\ cp /One-KVM/configs/os/tmpfiles.conf /usr/lib/tmpfiles.d/ && \\
mv /etc/kvmd/supervisord.conf /etc/supervisord.conf && \\
chmod +x /etc/update-motd.d/* || echo '警告chmod /etc/update-motd.d/* 失败' && \\ chmod +x /etc/update-motd.d/* || echo '警告chmod /etc/update-motd.d/* 失败' && \\
echo 'kvmd ALL=(ALL) NOPASSWD: /etc/kvmd/custom_atx/gpio.sh' >> /etc/sudoers && \\ echo 'kvmd ALL=(ALL) NOPASSWD: /etc/kvmd/custom_atx/gpio.sh' >> /etc/sudoers && \\
echo 'kvmd ALL=(ALL) NOPASSWD: /etc/kvmd/custom_atx/usbrelay_hid.sh' >> /etc/sudoers && \\ echo 'kvmd ALL=(ALL) NOPASSWD: /etc/kvmd/custom_atx/usbrelay_hid.sh' >> /etc/sudoers && \\
@ -210,7 +209,7 @@ install_webterm() {
echo "信息:在 chroot 环境中下载并安装 ttyd ($ttyd_arch)..." echo "信息:在 chroot 环境中下载并安装 ttyd ($ttyd_arch)..."
run_in_chroot " run_in_chroot "
curl -L https://gh.llkk.cc/https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.${ttyd_arch} -o /usr/bin/ttyd && \\ curl -L https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.${ttyd_arch} -o /usr/bin/ttyd && \\
chmod +x /usr/bin/ttyd && \\ chmod +x /usr/bin/ttyd && \\
mkdir -p /home/kvmd-webterm && \\ mkdir -p /home/kvmd-webterm && \\
chown kvmd-webterm /home/kvmd-webterm chown kvmd-webterm /home/kvmd-webterm

View File

@ -719,9 +719,6 @@
</tr> </tr>
</table> </table>
</div> </div>
<div class="hidden" id="msd-uploading-sub">
<hr>
</div>
<div class="hidden" id="msd-uploading-sub"> <div class="hidden" id="msd-uploading-sub">
<table class="kv"> <table class="kv">
<tr> <tr>

View File

@ -47,7 +47,7 @@ li.right.feature-disabled#msd-dropdown
{title: "Flash", value: "0"}, {title: "Flash", value: "0"},
]) Drive #[a(target="_blank" href="https://docs.pikvm.org/msd") mode]: ]) Drive #[a(target="_blank" href="https://docs.pikvm.org/msd") mode]:
td &nbsp; td &nbsp;
+menu_switch_td2("msd-rw-switch", false, false) Writable: +menu_switch_td2("msd-rw-switch", false, false, "msd-rw-switch") Writable:
tr tr
td(i18n="drive_file_display") Files td(i18n="drive_file_display") Files
td td
@ -79,8 +79,6 @@ li.right.feature-disabled#msd-dropdown
tr.hidden#msd-new-part tr.hidden#msd-new-part
td(i18n="drive_upload_partition") Upload partition: td(i18n="drive_upload_partition") Upload partition:
td(width="100%") #[select#msd-new-part-selector] td(width="100%") #[select#msd-new-part-selector]
div(id="msd-uploading-sub" class="hidden")
hr
.hidden#msd-uploading-sub .hidden#msd-uploading-sub
table.kv table.kv

View File

@ -122,6 +122,7 @@
"drive_unpackage_files":"Unpackage files from image", "drive_unpackage_files":"Unpackage files from image",
"drive_image_files":"Image Files", "drive_image_files":"Image Files",
"drive_normal_files":"Normal Files", "drive_normal_files":"Normal Files",
"drive_writable":"Writable:",
"atx-ask-switch":"Ask click confirmation", "atx-ask-switch":"Ask click confirmation",
"hid-recorder-loop-switch":"Infinite loop playback", "hid-recorder-loop-switch":"Infinite loop playback",

View File

@ -122,6 +122,7 @@
"drive_unpackage_files":"从镜像文件解压文件", "drive_unpackage_files":"从镜像文件解压文件",
"drive_image_files":"镜像文件模式", "drive_image_files":"镜像文件模式",
"drive_normal_files":"普通文件模式", "drive_normal_files":"普通文件模式",
"drive_writable":"可写:",

View File

@ -42,20 +42,34 @@ function getCookie(name)
return "" return ""
} }
var i18nLanguage = "zh"; function detectBrowserLanguage() {
var browserLang = navigator.language || navigator.userLanguage;
if (browserLang.startsWith('zh')) {
return 'zh';
} else if (browserLang.startsWith('en')) {
return 'en';
} else {
return 'zh';
}
}
var i18nLanguage = detectBrowserLanguage();
$(document).ready(function() { $(document).ready(function() {
if (getCookie('userLanguage')) { if (getCookie('userLanguage')) {
i18nLanguage = getCookie('userLanguage'); i18nLanguage = getCookie('userLanguage');
}
var no;
if (i18nLanguage == "zh") { if (i18nLanguage == "zh") {
no = 0; no = 0;
}else if (i18nLanguage == "en") { } else if (i18nLanguage == "en") {
no = 1; no = 1;
} }
$("#selectLanguage").each(function(){ $("#selectLanguage").each(function(){
$(this).find("option").eq(no).prop("selected",true) $(this).find("option").eq(no).prop("selected", true);
}); });
}
$("[i18n]").i18n({ $("[i18n]").i18n({
defaultLang: i18nLanguage, defaultLang: i18nLanguage,

View File

@ -337,10 +337,10 @@ export function Msd() {
} }
if (file) { if (file) {
let e_image = encodeURIComponent(file.name); let e_image = encodeURIComponent(file.name);
__http.open("POST", `${ROOT_PREFIX}api/msd/write?prefix=${e_prefix}&image=${e_image}&remove_incomplete=1`, true); __http.open("POST", `${ROOT_PREFIX}api/msd/write?prefix=${prefix}&image=${e_image}&remove_incomplete=1`, true);
} else { } else {
let e_url = encodeURIComponent($("msd-new-url").value); let e_url = encodeURIComponent($("msd-new-url").value);
__http.open("POST", `${ROOT_PREFIX}api/msd/write_remote?prefix=${e_prefix}&url=${e_url}&remove_incomplete=1`, true); __http.open("POST", `${ROOT_PREFIX}api/msd/write_remote?prefix=${prefix}&url=${e_url}&remove_incomplete=1`, true);
} }
__http.upload.timeout = 7 * 24 * 3600; __http.upload.timeout = 7 * 24 * 3600;
__http.onreadystatechange = __uploadStateChange; __http.onreadystatechange = __uploadStateChange;