WEBRTC前端播放 播放器组件封装

组件封装

<template><div><div class="option"><input v-model="useStun" type="checkbox" /><label for="use-stun">Use STUN server</label></div><button @click="startPlay">Start</button><form @submit.prevent="sendMessage"><div><p>input text</p><textareav-model="message"cols="2"rows="3"class="form-control"style="width: 600px; height: 50px"></textarea></div><button type="submit">Send</button></form><div id="media"><h2>Media</h2><videoref="rtcMediaPlayer"style="width: 600px"controlsautoplay></video></div></div>
</template><script setup>
import { ref, onMounted } from "vue";
import { SrsRtcWhipWhepAsync } from "@/utils/srs.sdk"; // 确保路径正确const useStun = ref(false);
const message = ref("");
const rtcMediaPlayer = ref(null);
let sdk = null;const startPlay = async () => {rtcMediaPlayer.value.style.display = "block";if (sdk) {sdk.close();}sdk = new SrsRtcWhipWhepAsync();console.log(" sdk.stream", sdk.stream);rtcMediaPlayer.value.srcObject = sdk.stream;// sdk.stream//   .getTracks()//   .forEach((track) => rtcMediaPlayer.value.srcObject.addTrack(track));const host = window.location.hostname;const url = `http://10.3.208.9:1985/rtc/v1/whep/?app=live&stream=livestream`;try {await sdk.play(url);} catch (reason) {sdk.close();rtcMediaPlayer.value.style.display = "none";console.error(reason);}
};const sendMessage = async () => {const response = await fetch("/human", {body: JSON.stringify({text: message.value,type: "echo",}),headers: {"Content-Type": "application/json",},method: "POST",});message.value = "";console.log("Message sent:", await response.json());
};onMounted(() => {rtcMediaPlayer.value.style.display = "none";
});
</script><style scoped>
button {padding: 8px 16px;
}video {width: 100%;
}.option {margin-bottom: 8px;
}#media {max-width: 1280px;
}
</style>

srs.sdk.js文件

//
// Copyright (c) 2013-2021 Winlin
//
// SPDX-License-Identifier: MIT
//"use strict";function SrsError(name, message) {this.name = name;this.message = message;this.stack = new Error().stack;
}
SrsError.prototype = Object.create(Error.prototype);
SrsError.prototype.constructor = SrsError;// Depends on adapter-7.4.0.min.js from https://github.com/webrtc/adapter
// Async-awat-prmise based SRS RTC Publisher.
function SrsRtcPublisherAsync() {var self = {};// https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMediaself.constraints = {audio: true,video: {width: { ideal: 320, max: 576 },},};// @see https://github.com/rtcdn/rtcdn-draft// @url The WebRTC url to play with, for example://      webrtc://r.ossrs.net/live/livestream// or specifies the API port://      webrtc://r.ossrs.net:11985/live/livestream// or autostart the publish://      webrtc://r.ossrs.net/live/livestream?autostart=true// or change the app from live to myapp://      webrtc://r.ossrs.net:11985/myapp/livestream// or change the stream from livestream to mystream://      webrtc://r.ossrs.net:11985/live/mystream// or set the api server to myapi.domain.com://      webrtc://myapi.domain.com/live/livestream// or set the candidate(eip) of answer://      webrtc://r.ossrs.net/live/livestream?candidate=39.107.238.185// or force to access https API://      webrtc://r.ossrs.net/live/livestream?schema=https// or use plaintext, without SRTP://      webrtc://r.ossrs.net/live/livestream?encrypt=false// or any other information, will pass-by in the query://      webrtc://r.ossrs.net/live/livestream?vhost=xxx//      webrtc://r.ossrs.net/live/livestream?token=xxxself.publish = async function (url) {var conf = self.__internal.prepareUrl(url);self.pc.addTransceiver("audio", { direction: "sendonly" });self.pc.addTransceiver("video", { direction: "sendonly" });//self.pc.addTransceiver("video", {direction: "sendonly"});//self.pc.addTransceiver("audio", {direction: "sendonly"});if (!navigator.mediaDevices &&window.location.protocol === "http:" &&window.location.hostname !== "localhost") {throw new SrsError("HttpsRequiredError",`Please use HTTPS or localhost to publish, read https://github.com/ossrs/srs/issues/2762#issuecomment-983147576`);}var stream = await navigator.mediaDevices.getUserMedia(self.constraints);// @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrackstream.getTracks().forEach(function (track) {self.pc.addTrack(track);// Notify about local track when stream is ok.self.ontrack && self.ontrack({ track: track });});var offer = await self.pc.createOffer();await self.pc.setLocalDescription(offer);var session = await new Promise(function (resolve, reject) {// @see https://github.com/rtcdn/rtcdn-draftvar data = {api: conf.apiUrl,tid: conf.tid,streamurl: conf.streamUrl,clientip: null,sdp: offer.sdp,};console.log("Generated offer: ", data);const xhr = new XMLHttpRequest();xhr.onload = function () {if (xhr.readyState !== xhr.DONE) return;if (xhr.status !== 200 && xhr.status !== 201) return reject(xhr);const data = JSON.parse(xhr.responseText);console.log("Got answer: ", data);return data.code ? reject(xhr) : resolve(data);};xhr.open("POST", conf.apiUrl, true);xhr.setRequestHeader("Content-type", "application/json");xhr.send(JSON.stringify(data));});await self.pc.setRemoteDescription(new RTCSessionDescription({ type: "answer", sdp: session.sdp }));session.simulator =conf.schema +"//" +conf.urlObject.server +":" +conf.port +"/rtc/v1/nack/";return session;};// Close the publisher.self.close = function () {self.pc && self.pc.close();self.pc = null;};// The callback when got local stream.// @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrackself.ontrack = function (event) {// Add track to stream of SDK.self.stream.addTrack(event.track);};// Internal APIs.self.__internal = {defaultPath: "/rtc/v1/publish/",prepareUrl: function (webrtcUrl) {var urlObject = self.__internal.parse(webrtcUrl);// If user specifies the schema, use it as API schema.var schema = urlObject.user_query.schema;schema = schema ? schema + ":" : window.location.protocol;var port = urlObject.port || 1985;if (schema === "https:") {port = urlObject.port || 443;}// @see https://github.com/rtcdn/rtcdn-draftvar api = urlObject.user_query.play || self.__internal.defaultPath;if (api.lastIndexOf("/") !== api.length - 1) {api += "/";}var apiUrl = schema + "//" + urlObject.server + ":" + port + api;for (var key in urlObject.user_query) {if (key !== "api" && key !== "play") {apiUrl += "&" + key + "=" + urlObject.user_query[key];}}// Replace /rtc/v1/play/&k=v to /rtc/v1/play/?k=vapiUrl = apiUrl.replace(api + "&", api + "?");var streamUrl = urlObject.url;return {apiUrl: apiUrl,streamUrl: streamUrl,schema: schema,urlObject: urlObject,port: port,tid: Number(parseInt(new Date().getTime() * Math.random() * 100)).toString(16).slice(0, 7),};},parse: function (url) {// @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascrivar a = document.createElement("a");a.href = url.replace("rtmp://", "http://").replace("webrtc://", "http://").replace("rtc://", "http://");var vhost = a.hostname;var app = a.pathname.substring(1, a.pathname.lastIndexOf("/"));var stream = a.pathname.slice(a.pathname.lastIndexOf("/") + 1);// parse the vhost in the params of app, that srs supports.app = app.replace("...vhost...", "?vhost=");if (app.indexOf("?") >= 0) {var params = app.slice(app.indexOf("?"));app = app.slice(0, app.indexOf("?"));if (params.indexOf("vhost=") > 0) {vhost = params.slice(params.indexOf("vhost=") + "vhost=".length);if (vhost.indexOf("&") > 0) {vhost = vhost.slice(0, vhost.indexOf("&"));}}}// when vhost equals to server, and server is ip,// the vhost is __defaultVhost__if (a.hostname === vhost) {var re = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;if (re.test(a.hostname)) {vhost = "__defaultVhost__";}}// parse the schemavar schema = "rtmp";if (url.indexOf("://") > 0) {schema = url.slice(0, url.indexOf("://"));}var port = a.port;if (!port) {// Finger out by webrtc url, if contains http or https port, to overwrite default 1985.if (schema === "webrtc" && url.indexOf(`webrtc://${a.host}:`) === 0) {port = url.indexOf(`webrtc://${a.host}:80`) === 0 ? 80 : 443;}// Guess by schema.if (schema === "http") {port = 80;} else if (schema === "https") {port = 443;} else if (schema === "rtmp") {port = 1935;}}var ret = {url: url,schema: schema,server: a.hostname,port: port,vhost: vhost,app: app,stream: stream,};self.__internal.fill_query(a.search, ret);// For webrtc API, we use 443 if page is https, or schema specified it.if (!ret.port) {if (schema === "webrtc" || schema === "rtc") {if (ret.user_query.schema === "https") {ret.port = 443;} else if (window.location.href.indexOf("https://") === 0) {ret.port = 443;} else {// For WebRTC, SRS use 1985 as default API port.ret.port = 1985;}}}return ret;},fill_query: function (query_string, obj) {// pure user query object.obj.user_query = {};if (query_string.length === 0) {return;}// split again for angularjs.if (query_string.indexOf("?") >= 0) {query_string = query_string.split("?")[1];}var queries = query_string.split("&");for (var i = 0; i < queries.length; i++) {var elem = queries[i];var query = elem.split("=");obj[query[0]] = query[1];obj.user_query[query[0]] = query[1];}// alias domain for vhost.if (obj.domain) {obj.vhost = obj.domain;}},};self.pc = new RTCPeerConnection(null);// To keep api consistent between player and publisher.// @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrack// @see https://webrtc.org/getting-started/media-devicesself.stream = new MediaStream();return self;
}// Depends on adapter-7.4.0.min.js from https://github.com/webrtc/adapter
// Async-await-promise based SRS RTC Player.
function SrsRtcPlayerAsync() {var self = {};// @see https://github.com/rtcdn/rtcdn-draft// @url The WebRTC url to play with, for example://      webrtc://r.ossrs.net/live/livestream// or specifies the API port://      webrtc://r.ossrs.net:11985/live/livestream//      webrtc://r.ossrs.net:80/live/livestream// or autostart the play://      webrtc://r.ossrs.net/live/livestream?autostart=true// or change the app from live to myapp://      webrtc://r.ossrs.net:11985/myapp/livestream// or change the stream from livestream to mystream://      webrtc://r.ossrs.net:11985/live/mystream// or set the api server to myapi.domain.com://      webrtc://myapi.domain.com/live/livestream// or set the candidate(eip) of answer://      webrtc://r.ossrs.net/live/livestream?candidate=39.107.238.185// or force to access https API://      webrtc://r.ossrs.net/live/livestream?schema=https// or use plaintext, without SRTP://      webrtc://r.ossrs.net/live/livestream?encrypt=false// or any other information, will pass-by in the query://      webrtc://r.ossrs.net/live/livestream?vhost=xxx//      webrtc://r.ossrs.net/live/livestream?token=xxxself.play = async function (url) {var conf = self.__internal.prepareUrl(url);self.pc.addTransceiver("audio", { direction: "recvonly" });self.pc.addTransceiver("video", { direction: "recvonly" });//self.pc.addTransceiver("video", {direction: "recvonly"});//self.pc.addTransceiver("audio", {direction: "recvonly"});var offer = await self.pc.createOffer();await self.pc.setLocalDescription(offer);var session = await new Promise(function (resolve, reject) {// @see https://github.com/rtcdn/rtcdn-draftvar data = {api: conf.apiUrl,tid: conf.tid,streamurl: conf.streamUrl,clientip: null,sdp: offer.sdp,};console.log("Generated offer: ", data);const xhr = new XMLHttpRequest();xhr.onload = function () {if (xhr.readyState !== xhr.DONE) return;if (xhr.status !== 200 && xhr.status !== 201) return reject(xhr);const data = JSON.parse(xhr.responseText);console.log("Got answer: ", data);return data.code ? reject(xhr) : resolve(data);};xhr.open("POST", conf.apiUrl, true);xhr.setRequestHeader("Content-type", "application/json");xhr.send(JSON.stringify(data));});await self.pc.setRemoteDescription(new RTCSessionDescription({ type: "answer", sdp: session.sdp }));session.simulator =conf.schema +"//" +conf.urlObject.server +":" +conf.port +"/rtc/v1/nack/";return session;};// Close the player.self.close = function () {self.pc && self.pc.close();self.pc = null;};// The callback when got remote track.// Note that the onaddstream is deprecated, @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/onaddstreamself.ontrack = function (event) {// https://webrtc.org/getting-started/remote-streamsself.stream.addTrack(event.track);};// Internal APIs.self.__internal = {defaultPath: "/rtc/v1/play/",prepareUrl: function (webrtcUrl) {var urlObject = self.__internal.parse(webrtcUrl);// If user specifies the schema, use it as API schema.var schema = urlObject.user_query.schema;schema = schema ? schema + ":" : window.location.protocol;var port = urlObject.port || 1985;if (schema === "https:") {port = urlObject.port || 443;}// @see https://github.com/rtcdn/rtcdn-draftvar api = urlObject.user_query.play || self.__internal.defaultPath;if (api.lastIndexOf("/") !== api.length - 1) {api += "/";}var apiUrl = schema + "//" + urlObject.server + ":" + port + api;for (var key in urlObject.user_query) {if (key !== "api" && key !== "play") {apiUrl += "&" + key + "=" + urlObject.user_query[key];}}// Replace /rtc/v1/play/&k=v to /rtc/v1/play/?k=vapiUrl = apiUrl.replace(api + "&", api + "?");var streamUrl = urlObject.url;return {apiUrl: apiUrl,streamUrl: streamUrl,schema: schema,urlObject: urlObject,port: port,tid: Number(parseInt(new Date().getTime() * Math.random() * 100)).toString(16).slice(0, 7),};},parse: function (url) {// @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascrivar a = document.createElement("a");a.href = url.replace("rtmp://", "http://").replace("webrtc://", "http://").replace("rtc://", "http://");var vhost = a.hostname;var app = a.pathname.substring(1, a.pathname.lastIndexOf("/"));var stream = a.pathname.slice(a.pathname.lastIndexOf("/") + 1);// parse the vhost in the params of app, that srs supports.app = app.replace("...vhost...", "?vhost=");if (app.indexOf("?") >= 0) {var params = app.slice(app.indexOf("?"));app = app.slice(0, app.indexOf("?"));if (params.indexOf("vhost=") > 0) {vhost = params.slice(params.indexOf("vhost=") + "vhost=".length);if (vhost.indexOf("&") > 0) {vhost = vhost.slice(0, vhost.indexOf("&"));}}}// when vhost equals to server, and server is ip,// the vhost is __defaultVhost__if (a.hostname === vhost) {var re = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;if (re.test(a.hostname)) {vhost = "__defaultVhost__";}}// parse the schemavar schema = "rtmp";if (url.indexOf("://") > 0) {schema = url.slice(0, url.indexOf("://"));}var port = a.port;if (!port) {// Finger out by webrtc url, if contains http or https port, to overwrite default 1985.if (schema === "webrtc" && url.indexOf(`webrtc://${a.host}:`) === 0) {port = url.indexOf(`webrtc://${a.host}:80`) === 0 ? 80 : 443;}// Guess by schema.if (schema === "http") {port = 80;} else if (schema === "https") {port = 443;} else if (schema === "rtmp") {port = 1935;}}var ret = {url: url,schema: schema,server: a.hostname,port: port,vhost: vhost,app: app,stream: stream,};self.__internal.fill_query(a.search, ret);// For webrtc API, we use 443 if page is https, or schema specified it.if (!ret.port) {if (schema === "webrtc" || schema === "rtc") {if (ret.user_query.schema === "https") {ret.port = 443;} else if (window.location.href.indexOf("https://") === 0) {ret.port = 443;} else {// For WebRTC, SRS use 1985 as default API port.ret.port = 1985;}}}return ret;},fill_query: function (query_string, obj) {// pure user query object.obj.user_query = {};if (query_string.length === 0) {return;}// split again for angularjs.if (query_string.indexOf("?") >= 0) {query_string = query_string.split("?")[1];}var queries = query_string.split("&");for (var i = 0; i < queries.length; i++) {var elem = queries[i];var query = elem.split("=");obj[query[0]] = query[1];obj.user_query[query[0]] = query[1];}// alias domain for vhost.if (obj.domain) {obj.vhost = obj.domain;}},};self.pc = new RTCPeerConnection(null);// Create a stream to add track to the stream, @see https://webrtc.org/getting-started/remote-streamsself.stream = new MediaStream();// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ontrackself.pc.ontrack = function (event) {if (self.ontrack) {self.ontrack(event);}};return self;
}// Depends on adapter-7.4.0.min.js from https://github.com/webrtc/adapter
// Async-awat-prmise based SRS RTC Publisher by WHIP.
function SrsRtcWhipWhepAsync() {var self = {};// https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMediaself.constraints = {audio: true,video: {width: { ideal: 320, max: 576 },},};// See https://datatracker.ietf.org/doc/draft-ietf-wish-whip/// @url The WebRTC url to publish with, for example://      http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream// @options The options to control playing, supports://      videoOnly: boolean, whether only play video, default to false.//      audioOnly: boolean, whether only play audio, default to false.self.publish = async function (url, options) {if (url.indexOf("/whip/") === -1)throw new Error(`invalid WHIP url ${url}`);if (options?.videoOnly && options?.audioOnly)throw new Error(`The videoOnly and audioOnly in options can't be true at the same time`);if (!options?.videoOnly) {self.pc.addTransceiver("audio", { direction: "sendonly" });} else {self.constraints.audio = false;}if (!options?.audioOnly) {self.pc.addTransceiver("video", { direction: "sendonly" });} else {self.constraints.video = false;}if (!navigator.mediaDevices &&window.location.protocol === "http:" &&window.location.hostname !== "localhost") {throw new SrsError("HttpsRequiredError",`Please use HTTPS or localhost to publish, read https://github.com/ossrs/srs/issues/2762#issuecomment-983147576`);}var stream = await navigator.mediaDevices.getUserMedia(self.constraints);// @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrackstream.getTracks().forEach(function (track) {self.pc.addTrack(track);// Notify about local track when stream is ok.self.ontrack && self.ontrack({ track: track });});var offer = await self.pc.createOffer();await self.pc.setLocalDescription(offer);const answer = await new Promise(function (resolve, reject) {console.log(`Generated offer: ${offer.sdp}`);const xhr = new XMLHttpRequest();xhr.onload = function () {if (xhr.readyState !== xhr.DONE) return;if (xhr.status !== 200 && xhr.status !== 201) return reject(xhr);const data = xhr.responseText;console.log("Got answer: ", data);return data.code ? reject(xhr) : resolve(data);};xhr.open("POST", url, true);xhr.setRequestHeader("Content-type", "application/sdp");xhr.send(offer.sdp);});await self.pc.setRemoteDescription(new RTCSessionDescription({ type: "answer", sdp: answer }));return self.__internal.parseId(url, offer.sdp, answer);};// See https://datatracker.ietf.org/doc/draft-ietf-wish-whip/// @url The WebRTC url to play with, for example://      http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream// @options The options to control playing, supports://      videoOnly: boolean, whether only play video, default to false.//      audioOnly: boolean, whether only play audio, default to false.self.play = async function (url, options) {if (url.indexOf("/whip-play/") === -1 && url.indexOf("/whep/") === -1)throw new Error(`invalid WHEP url ${url}`);if (options?.videoOnly && options?.audioOnly)throw new Error(`The videoOnly and audioOnly in options can't be true at the same time`);if (!options?.videoOnly)self.pc.addTransceiver("audio", { direction: "recvonly" });if (!options?.audioOnly)self.pc.addTransceiver("video", { direction: "recvonly" });var offer = await self.pc.createOffer();await self.pc.setLocalDescription(offer);const answer = await new Promise(function (resolve, reject) {console.log(`Generated offer: ${offer.sdp}`);const xhr = new XMLHttpRequest();xhr.onload = function () {if (xhr.readyState !== xhr.DONE) return;if (xhr.status !== 200 && xhr.status !== 201) return reject(xhr);const data = xhr.responseText;console.log("Got answer: ", data);return data.code ? reject(xhr) : resolve(data);};xhr.open("POST", url, true);xhr.setRequestHeader("Content-type", "application/sdp");xhr.send(offer.sdp);});await self.pc.setRemoteDescription(new RTCSessionDescription({ type: "answer", sdp: answer }));return self.__internal.parseId(url, offer.sdp, answer);};// Close the publisher.self.close = function () {self.pc && self.pc.close();self.pc = null;};// The callback when got local stream.// @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrackself.ontrack = function (event) {// Add track to stream of SDK.self.stream.addTrack(event.track);};self.pc = new RTCPeerConnection(null);// To keep api consistent between player and publisher.// @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrack// @see https://webrtc.org/getting-started/media-devicesself.stream = new MediaStream();// Internal APIs.self.__internal = {parseId: (url, offer, answer) => {let sessionid = offer.substr(offer.indexOf("a=ice-ufrag:") + "a=ice-ufrag:".length);sessionid = sessionid.substr(0, sessionid.indexOf("\n") - 1) + ":";sessionid += answer.substr(answer.indexOf("a=ice-ufrag:") + "a=ice-ufrag:".length);sessionid = sessionid.substr(0, sessionid.indexOf("\n"));const a = document.createElement("a");a.href = url;return {sessionid: sessionid, // Should be ice-ufrag of answer:offer.simulator: a.protocol + "//" + a.host + "/rtc/v1/nack/",};},};// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ontrackself.pc.ontrack = function (event) {if (self.ontrack) {self.ontrack(event);}};return self;
}// Format the codec of RTCRtpSender, kind(audio/video) is optional filter.
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/WebRTC_codecs#getting_the_supported_codecs
function SrsRtcFormatSenders(senders, kind) {var codecs = [];senders.forEach(function (sender) {var params = sender.getParameters();params &&params.codecs &&params.codecs.forEach(function (c) {if (kind && sender.track.kind !== kind) {return;}if (c.mimeType.indexOf("/red") > 0 ||c.mimeType.indexOf("/rtx") > 0 ||c.mimeType.indexOf("/fec") > 0) {return;}var s = "";s += c.mimeType.replace("audio/", "").replace("video/", "");s += ", " + c.clockRate + "HZ";if (sender.track.kind === "audio") {s += ", channels: " + c.channels;}s += ", pt: " + c.payloadType;codecs.push(s);});});return codecs.join(", ");
}export {SrsError,SrsRtcPublisherAsync,SrsRtcWhipWhepAsync,SrsRtcFormatSenders,SrsRtcPlayerAsync,
};

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/67773.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(五)ROS通信编程——参数服务器

前言 参数服务器在ROS中主要用于实现不同节点之间的数据共享&#xff08;P2P&#xff09;。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据&#xff0c;关…

攻防靶场(34):隐蔽的计划任务提权 Funbox1

目录 1. 侦查 1.1 收集目标网络信息&#xff1a;IP地址 1.2 主动扫描&#xff1a;扫描IP地址段 1.3 搜索目标网站 2. 初始访问 2.1 有效账户&#xff1a;默认账户 2.2 利用面向公众的应用 2.3 有效账户&#xff1a;默认账户 3. 权限提升 3.1 计划任务/作业&#xff1a;Cron 靶场…

嵌入式入门Day38

C Day1 第一个C程序C中的输入输出输出操作coutcin练习 命名空间使用方法自定义命名空间冲突问题 C对字符串的扩充C风格字符串的使用定义以及初始化C风格字符串与C风格字符串的转换C风格的字符串的关系运算常用的成员变量输入方法 布尔类型C对堆区空间使用的扩充作业 第一个C程序…

kubernetes第七天

1.影响pod调度的因素 nodeName 节点名 resources 资源限制 hostNetwork 宿主机网络 污点 污点容忍 Pod亲和性 Pod反亲和性 节点亲和性 2.污点 通常是作用于worker节点上&#xff0c;其可以影响pod的调度 语法&#xff1a;key[value]:effect effect:[ɪˈfek…

直流无刷电机控制(FOC):电流模式

目录 概述 1 系统框架结构 1.1 硬件模块介绍 1.2 硬件实物图 1.3 引脚接口定义 2 代码实现 2.1 软件架构 2.2 电流检测函数 3 电流环功能实现 3.1 代码实现 3.2 测试代码实现 4 测试 概述 本文主要介绍基于DengFOC的库函数&#xff0c;实现直流无刷电机控制&#x…

Google发布图像生成新工具Whisk:无需复杂提示词,使用图像和人工智能将想法可视化并重新混合

Whisk 是 Google Labs 的一项新实验&#xff0c;可使用图像进行快速而有趣的创作过程。Whisk不会生成带有长篇详细文本提示的图像&#xff0c;而是使用图像进行提示。只需拖入图像&#xff0c;即可开始创建。 whisk总结如下&#xff1a; Whisk 是 Google 实验室最新的生成图像实…

【面试题】技术场景 4、负责项目时遇到的棘手问题及解决方法

工作经验一年以上程序员必问问题 面试题概述 问题为在负责项目时遇到的棘手问题及解决方法&#xff0c;主要考察开发经验与技术水平&#xff0c;回答不佳会影响面试印象。提供四个回答方向&#xff0c;准备其中一个方向即可。 1、设计模式应用方向 以登录为例&#xff0c;未…

MySQL 子查询(重在练习)

第九章: 子查询 1.子查询的需求分析和问题解决 1.1基本使用 子查询(内查询)在主查询之前一次执行完成 子查询的结果被主查询(外查询)调用 注意事项 子查询要包含在括号内 将子查询放在比较条件的右侧 单行操作符对应单行子查询,多行操作符对应多行子查询 1.2子查询的分类…

海外招聘丨卡尔斯塔德大学—互联网隐私和安全副高级讲师

雇主简介 卡尔斯塔德大学以研究、教育和合作为基础。通过让社区参与知识发展&#xff0c;卡尔斯塔德大学为地区、国家和国际研究和教育发展做出了贡献&#xff0c;旨在提高可持续性、民主和健康。我们富有创造力的学术环境以好奇心、勇气和毅力为特征。通过采取批判性方法&…

CTFshow—文件包含

Web78-81 Web78 这题是最基础的文件包含&#xff0c;直接?fileflag.php是不行的&#xff0c;不知道为啥&#xff0c;直接用下面我们之前在命令执行讲过的payload即可。 ?filephp://filter/readconvert.base64-encode/resourceflag.php Web79 这题是过滤了php&#xff0c;…

iOS实际开发中使用Alamofire实现多文件上传(以个人相册为例)

引言 在移动应用中&#xff0c;图片上传是一个常见的功能&#xff0c;尤其是在个人中心或社交平台场景中&#xff0c;用户经常需要上传图片到服务器&#xff0c;用以展示个人风采或记录美好瞬间。然而&#xff0c;实现多图片上传的过程中&#xff0c;如何设计高效的上传逻辑并…

Cannot run program “docker“: CreateProcess error=2,系统找不到指定的文件

今天被这个问题坑了, 网上教程全是直接装插件就行 ,结果我连接可以成功 但是执行docker compose 就会出错, 检测配置 报错com.intellil,execution,process.ProcessNotCreatedException: Cannot run program “docker”: CreateProcess error2,系统找不到指定的文件 gpt 要我去…

Blender 2D动画与MATLAB数学建模:跨界融合的创新实践探索

文章目录 一、数据交换&#xff1a;从科学计算到创意表达的桥梁二、脚本自动化&#xff1a;从手动操作到无缝连接的升级三、跨界融合的创新实践意义《Blender 2D动画制作从入门到精通》亮点内容简介作者简介 《MATLAB数学建模从入门到精通》亮点内容简介作者简介 在数字创意与科…

HarmonyOS Next 日志工具介绍

HarmonyOS Next 日志工具介绍 在HarmonyOS Next开发中&#xff0c;日志是我们调试定位问题的主要手段&#xff0c;不管是hilog还是console&#xff0c;最终都可以输出到DevEco Studio的日志模块中&#xff1a; 在这里可以过滤应用进程、日志级别、日志内容呢&#xff0c;也可…

NUTTX移植到STM32

STM32移植NUTTX 1. Ubuntu下搭建开发环境1.1 先决条件1.2 下载 NuttX1.3 使用Make 进行编译1.4 烧录运行 2.通过NUTTX点亮LED2.1 部署操作系统2.2 修改配置文件2.3 编译运行程序 开发板&#xff1a;DshanMCUF407 官方开发文档&#xff1a;安装 — NuttX latest 文档 参考文档&…

【微服务】4、服务保护

微服务架构与组件介绍 单体架构拆分&#xff1a;黑马商城早期为单体架构&#xff0c;后拆分为微服务架构。跨服务调用与组件使用 服务拆分后存在跨服务远程调用&#xff0c;如下单需查询商品信息&#xff0c;使用openfeign组件解决。服务间调用关系复杂&#xff0c;需维护服务…

【网络安全 | 漏洞挖掘】通过模拟功能实现提权(Bugcrowd)

未经许可,不得转载。 我将与大家分享我在 Bugcrowd 的某个项目中发现的一个漏洞,该项目中有一个“用户模拟”功能。 什么是用户模拟? 用户模拟允许管理员在不知晓用户凭据的情况下“以用户身份登录”。这种功能常见于管理员需要调试问题、审查用户权限或解决投诉的平台中。…

安装MySQL的五种方法(Linux系统和Windows系统)

一.在Linux系统中安装MySQL 第一种方法:在线YUM仓库 首先打开MySQL官网首页 www.mysql.com 找到【DOWNLOADS】选项&#xff0c;点击 下拉&#xff0c;找到 【MySQL Community(GPL) Downloads】 在社区版下载页面中&#xff0c;【 MySQL Yum Repository 】链接为在线仓库安装…

【Spring Boot 应用开发】-01 初识

特性 Spring Boot 是由 Pivotal 团队提供的全新框架&#xff0c;其设计目的是帮助开发者快速创建独立的、生产级的基于 Spring 框架的应用程序。以下是 Spring Boot 的一些主要特点&#xff1a; 简化配置&#xff1a;Spring Boot 提供了自动配置机制&#xff0c;能够根据类路径…

AR 眼镜之-拍照/录像动效切换-实现方案

目录 &#x1f4c2; 前言 AR 眼镜系统版本 拍照/录像动效切换 1. &#x1f531; 技术方案 1.1 技术方案概述 1.2 实现方案 1&#xff09;第一阶段动效 2&#xff09;第二阶段动效 2. &#x1f4a0; 默认代码配置 2.1 XML 初始布局 2.2 监听滑动对 View 改变 3. ⚛️…