自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

前端與硬件設(shè)備交互探秘,最全總結(jié)!

開發(fā) 前端
在現(xiàn)代Web開發(fā)中,處理用戶輸入事件是構(gòu)建交互式應(yīng)用的關(guān)鍵部分。這些輸入事件可以來自多種設(shè)備,包括鍵盤、鼠標(或觸控板)、觸摸屏以及游戲控制器等。

隨著技術(shù)的發(fā)展,前端技術(shù)與硬件設(shè)備的交互模式正變得日益豐富多樣。從基礎(chǔ)的點擊、滑動操作,進化到高級的傳感器數(shù)據(jù)捕獲及設(shè)備遠程操控,前端技術(shù)正持續(xù)跨越傳統(tǒng)的交互壁壘,為用戶塑造出更為便捷且智能的使用體驗。本文就來對前端與硬件交互多種方式進行全面盤點。

接收設(shè)備的輸入

在現(xiàn)代Web開發(fā)中,處理用戶輸入事件是構(gòu)建交互式應(yīng)用的關(guān)鍵部分。這些輸入事件可以來自多種設(shè)備,包括鍵盤、鼠標(或觸控板)、觸摸屏以及游戲控制器等。

鍵盤事件

鍵盤事件是最常見的用戶輸入方式之一,包括按鍵按下(keydown)、按鍵釋放(keyup)等事件。

  • keydown:當按鍵被按下時觸發(fā)。
  • keyup:當按鍵被釋放時觸發(fā)。

監(jiān)聽鍵盤事件的基本方法是使用addEventListener方法:

document.addEventListener('keydown', function(event) {  
    // 使用event.key來獲取按鍵的值  
    console.log('Key down:', event.key);  
});

Pointer事件

Pointer 事件是一個統(tǒng)一的指針輸入模型,旨在處理所有類型的指針輸入,包括鼠標、觸控筆和觸摸。Pointer事件包括pointerdown、pointerup、pointermove等。

  • pointerdown:當指針按下時觸發(fā)。
  • pointerup:當指針釋放時觸發(fā)。
  • pointermove:當指針移動時觸發(fā)。

監(jiān)聽Pointer事件的例子:

document.addEventListener('pointerdown', function(event) {
    console.log('Pointer down at:', event.clientX, event.clientY);  
});

還可以直接使用鼠標事件,常見的鼠標事件包括:

  • click:單擊鼠標左鍵時觸發(fā)。
  • dblclick:雙擊鼠標左鍵時觸發(fā)。
  • mousedown:鼠標按鈕被按下時觸發(fā)。
  • mouseup:鼠標按鈕被松開時觸發(fā)。
  • mousemove:鼠標在元素上移動時觸發(fā)。
  • mouseenter:鼠標進入元素時觸發(fā)。
  • mouseleave:鼠標離開元素時觸發(fā)。
  • contextmenu:用戶右鍵點擊時觸發(fā)。
  • wheel:鼠標滾輪滾動時觸發(fā)。
  • auxclick:輔助鍵(如中鍵或右鍵)被點擊時觸發(fā)。

例子:

document.addEventListener('mousedown', function(event) {  
    // 使用event.button來判斷哪個鼠標按鈕被按下  
    let buttonPressed;  
    switch (event.button) {  
        case 0:  
            buttonPressed = 'Left button';  
            break;  
        case 1:  
            buttonPressed = 'Middle button';  
            break;  
        case 2:  
            buttonPressed = 'Right button';  
            break;  
        default:  
            buttonPressed = 'Unknown button';  
    }  

    console.log(buttonPressed);

    // 如果按下了右鍵,則阻止默認的上下文菜單  
    if (event.button === 2) {  
        event.preventDefault();
    }  
});

mousedown事件對象的button屬性表示被按下的鼠標按鈕。這個屬性的值如下:

  • 0:表示主按鈕(通常是左鍵)。
  • 1:表示中間按鈕(通常是滾輪按鈕,但不是所有鼠標都有)。
  • 2:表示次按鈕(通常是右鍵)。

游戲控制器

Gamepad API 允許 Web 應(yīng)用檢測并響應(yīng)來自游戲控制器的輸入,包括按鈕按壓和軸移動。這對于開發(fā)需要精確控制的游戲或應(yīng)用非常有用。

使用 Gamepad API,首先需要檢查是否有連接的游戲控制器:

function checkGamepads() {  
    const gamepads = navigator.getGamepads();  
    for (let i = 0; i < gamepads.length; i++) {  
        if (gamepads[i]) {  
            console.log('Gamepad connected:', gamepads[i]);  
            // 處理游戲控制器輸入  
        }  
    }  
}  
  
// 定期檢查是否有游戲控制器連接  
setInterval(checkGamepads, 100);

一旦檢測到游戲控制器,可以訪問其buttons和axes屬性來讀取按鈕狀態(tài)和軸位置:

if (gamepad.buttons[0].pressed) {  
    console.log('Button 0 pressed');  
}  
  
console.log('Axis 0:', gamepad.axes[0]); // 通常表示左右移動  
console.log('Axis 1:', gamepad.axes[1]); // 通常表示上下移動

獲取音頻和視頻

在現(xiàn)代Web開發(fā)中,訪問和處理音頻與視頻流是一項強大的功能,它允許開發(fā)者創(chuàng)建實時通信應(yīng)用、視頻錄制工具、音頻處理應(yīng)用等。MediaDevices.getUserMedia() API 是實現(xiàn)這一功能的關(guān)鍵接口,它允許Web應(yīng)用請求訪問用戶的音頻和/或視頻設(shè)備(如攝像頭和麥克風(fēng)),并獲取實時媒體流。

獲取實時音頻和視頻流

MediaDevices.getUserMedia() 是一個異步函數(shù),它提示用戶允許Web應(yīng)用訪問其音頻和/或視頻設(shè)備。一旦用戶授權(quán),該函數(shù)返回一個 Promise,該 Promise 解析為一個 MediaStream 對象,該對象包含了來自音頻和/或視頻設(shè)備的實時數(shù)據(jù)。

navigator.mediaDevices.getUserMedia({ audio: true, video: true })  
  .then(function(stream) {  
    // 使用視頻流,例如將其顯示在video元素上  
    var video = document.querySelector('video');  
    video.srcObject = stream;  
    video.play();  
  })  
  .catch(function(err) {  
    console.error("Error accessing media devices.", err);  
  });

注意,要使用攝像頭或麥克風(fēng),需要申請權(quán)限。navigator.mediaDevices.getUserMedia() 的第一個參數(shù)是一個對象,用于指定詳細信息和每種媒體類型的要求例如,如果要訪問攝像頭,則第一個參數(shù)應(yīng)為 {video: true}。如需同時使用麥克風(fēng)和攝像頭,就要傳遞 {video: true, audio: true}。

瀏覽器在調(diào)用 navigator.mediaDevices.getUserMedia() 時顯示權(quán)限對話框, 讓用戶能夠選擇授予或拒絕對其攝像頭/麥克風(fēng)的訪問權(quán)限。

控制攝像頭

在訪問用戶攝像頭前,需要獲取用戶的授權(quán)。這里還是調(diào)用navigator.mediaDevices.getUserMedia()方法來實現(xiàn),它會返回一個Promise對象。當用戶同意或拒絕訪問攝像頭時,Promise對象會相應(yīng)地resolve或reject。

const constraints = { video: true, audio: true };  
try {  
  const stream = await navigator.mediaDevices.getUserMedia(constraints);  
  // 成功獲取到視頻流,可以在這里進行后續(xù)處理  
} catch (err) {  
  // 用戶拒絕或其他錯誤,可以在這里處理錯誤  
  console.error("Error accessing media devices.", err);  
}

成功獲取到視頻流后,可以將其賦值給HTML中的元素的srcObject屬性,并調(diào)用play()方法播放視頻流。

<video id="video" width="640" height="480" autoplay></video>  
<script>  
  const video = document.querySelector('#video');  
  navigator.mediaDevices.getUserMedia({ video: true, audio: false })  
    .then(function(stream) {  
      video.srcObject = stream;  
      video.play();  
    })  
    .catch(function(err) {  
      console.error("Error accessing media devices.", err);  
    });  
</script>

可以通過MediaStream API提供的getVideoTracks()方法可以獲取到視頻軌道,并通過enabled屬性來打開或關(guān)閉攝像頭。

const tracks = stream.getVideoTracks();  
tracks[0].enabled = false; // 關(guān)閉第一條視頻軌道(即攝像頭)

可以使用MediaRecorder API來錄制視頻并保存為文件。

const mediaRecorder = new MediaRecorder(stream);  
let chunks = [];  
  
mediaRecorder.ondataavailable = function(event) {  
  chunks.push(event.data);  
};  
  
mediaRecorder.onstop = function() {  
  const blob = new Blob(chunks, { type: 'video/mp4' });  
  const videoURL = window.URL.createObjectURL(blob);  
  // 這里可以將videoURL賦值給某個<video>元素的src屬性來播放錄制的視頻  
  // 或者將blob對象上傳到服務(wù)器  
  chunks = []; // 清空chunks數(shù)組,以便下次錄制  
};  
  
// 開始錄制  
mediaRecorder.start();  
  
// 停止錄制  
// mediaRecorder.stop(); // 可以在需要的時候調(diào)用

可以使用Canvas API對當前攝像頭畫面進行截圖。

const canvas = document.createElement('canvas');  
canvas.width = video.videoWidth;  
canvas.height = video.videoHeight;  
const ctx = canvas.getContext('2d');  
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);  
// 將canvas內(nèi)容轉(zhuǎn)換為圖片URL并顯示或下載  
const imageURL = canvas.toDataURL('image/png');  
// 可以在這里將imageURL賦值給某個<img>元素的src屬性來顯示圖片,或者使用a標簽的download屬性來下載圖片

使用設(shè)備進行打印

當調(diào)用 window.print() 方法時,瀏覽器會顯示一個打印對話框,允許用戶配置打印設(shè)置(如頁面布局、紙張大小、打印份數(shù)等)。

使用設(shè)備進行身份驗證

Web Authentication API 是一個現(xiàn)代、開放標準的 API,旨在通過公鑰加密技術(shù)來簡化用戶認證過程,同時增強安全性。它支持多種身份驗證方式,包括使用藍牙、NFC(近場通信)、USB漫游設(shè)備(如U2F或FIDO2身份驗證器)以及平臺身份驗證器(如內(nèi)置在筆記本電腦或智能手機中的指紋識別器或屏幕鎖定機制)。Authentication 它利用公鑰密碼學(xué),在用戶的設(shè)備上生成密鑰對(公鑰和私鑰),其中公鑰存儲在服務(wù)器上,私鑰則安全地保存在用戶設(shè)備上。

注意:在 Web Authentication API 中,“挑戰(zhàn)”(challenge)指的是一個由服務(wù)器生成的唯一、隨機的數(shù)據(jù)字符串。它有助于防止重放攻擊、增強安全性,并確保請求的真實性和完整性。

注冊過程

  • 生成挑戰(zhàn):服務(wù)器生成一個唯一的挑戰(zhàn)(通常是一個隨機字節(jié)數(shù)組),并將其發(fā)送給客戶端。
  • 調(diào)用API:客戶端使用navigator.credentials.create()方法開始注冊過程。該方法接受一個包含多個選項的對象作為參數(shù),包括應(yīng)用ID(通常是域名的哈希值)、用戶ID(如用戶名或郵箱地址)、公鑰參數(shù)(指定使用的公鑰算法和類型)以及挑戰(zhàn)等。
  • 用戶交互:用戶被提示選擇或插入一個身份驗證器,并按照設(shè)備要求進行身份驗證(如輸入PIN碼、指紋識別等)。
  • 生成并返回憑據(jù):身份驗證器生成一個公鑰憑據(jù),并將其與用戶的私鑰一起存儲。公鑰和必要的元數(shù)據(jù)(如認證器類型、公鑰算法等)被封裝在一個響應(yīng)對象中,并返回給客戶端。
  • 存儲憑據(jù):客戶端將響應(yīng)對象發(fā)送回服務(wù)器,服務(wù)器提取公鑰并存儲在數(shù)據(jù)庫中,與用戶ID相關(guān)聯(lián)。

認證過程

  • 生成挑戰(zhàn):與注冊過程類似,服務(wù)器生成一個新的挑戰(zhàn)。
  • 調(diào)用API:客戶端使用navigator.credentials.get()方法開始認證過程。該方法接受一個包含挑戰(zhàn)、應(yīng)用ID以及允許重用的憑據(jù)列表(可選)的對象作為參數(shù)。
  • 用戶交互:用戶再次被提示選擇或插入身份驗證器,并按照設(shè)備要求進行身份驗證。
  • 生成并返回斷言:身份驗證器使用私鑰簽署挑戰(zhàn),并將簽名連同憑據(jù)ID封裝在一個斷言對象中,返回給客戶端。
  • 驗證斷言:客戶端將斷言對象發(fā)送回服務(wù)器,服務(wù)器使用存儲的公鑰驗證簽名,以確認用戶身份。

訪問設(shè)備上的文件

在Web開發(fā)中,處理本地文件的需求很常見。隨著Web技術(shù)的發(fā)展,現(xiàn)代瀏覽器提供了幾種API來處理用戶文件,其中包括File System Access API和較老的File API。

File System Access API

File System Access API 提供了 showOpenFilePicker 和 showSaveFilePicker 方法,分別用于打開文件選擇對話框和保存文件對話框。

async function readFileAndSave() {
  try {
    // 打開文件選擇對話框
    const [fileHandle] = await window.showOpenFilePicker();
    
    // 讀取文件內(nèi)容
    const file = await fileHandle.getFile();
    const contents = await file.text();
    
    console.log('文件內(nèi)容:', contents);
    
    // 打開保存文件對話框
    const saveOptions = {
      suggestedName: 'saved-file.txt',
      types: [
        {
          description: 'Text files',
          accept: {
            'text/plain': ['.txt'],
          },
        },
      ],
    };
    
    const saveHandle = await window.showSaveFilePicker(saveOptions);
    
    // 寫入文件內(nèi)容
    const writableStream = await saveHandle.createWritable();
    await writableStream.write(contents);
    await writableureStream.close();
    
    console.log('文件已保存');
  } catch (error) {
    console.error('發(fā)生錯誤:', error);
  }
}

File API

如果 File System Access API 不可用,可以使用 File API 來實現(xiàn)類似的功能。File API 提供了 FileReader 對象,用于讀取文件內(nèi)容。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>讀取文件</title>

</head>

<body>
  <input type="file" id="fileInput" multiple>
  <pre id="fileContent"></pre>

  <script>
    document.getElementById('fileInput').addEventListener('change', function(event) {
      const files = event.target.files;
      const fileContentElement = document.getElementById('fileContent');
      
      fileContentElement.textContent = '';
      
      for (const file of files) {
        const reader = new FileReader();
        
        reader.onload = function(e) {
          fileContentElement.textContent += e.target.result + '\n';
        };
        
        reader.readAsText(file);
      }
    });
  </script>

</body>

</html>

在這個例子中,創(chuàng)建了一個文件輸入框,用戶可以通過它選擇本地文件。當用戶選擇文件后,使用 FileReader 對象來讀取文件內(nèi)容,并將其顯示在頁面上。

訪問設(shè)備上的傳感器

通用傳感器 API(Generic Sensor API)是一種允許 Web 應(yīng)用訪問設(shè)備上的傳感器數(shù)據(jù)的標準。這些傳感器包括移動傳感器(如加速度計和陀螺儀)以及環(huán)境傳感器(如環(huán)境光傳感器和磁力計)。這些API使得網(wǎng)頁和應(yīng)用能夠利用設(shè)備的硬件傳感器來提供更豐富的用戶體驗。

通用傳感器 API 的主要組件如下:

  • Sensor API:提供了一個通用的接口來訪問各種類型的傳感器數(shù)據(jù)。
  • Motion Sensors:包括加速度計(Accelerometer)和陀螺儀(Gyroscope)。
  • Orientation Sensors:通常與設(shè)備的方向有關(guān),可以提供關(guān)于設(shè)備方向的詳細信息。
  • Environmental Sensors:包括環(huán)境光傳感器和磁力計。

使用加速度計:

if ('Accelerometer' in window) {
  const accelerometer = new Accelerometer();

  accelerometer.addEventListener('reading', () => {
    console.log('Acceleration X:', accelerometer.x);
    console.log('Acceleration Y:', accelerometer.y);
    console.log('Acceleration Z:', accelerometer.z);
  });

  accelerometer.start();

  // 停止傳感器
  // accelerometer.stop();
} else {
  console.log('Accelerometer is not supported on this device.');
}

使用環(huán)境光傳感器:

if ('AmbientLightSensor' in window) {
  const ambientLightSensor = new AmbientLightSensor();

  ambientLightSensor.addEventListener('reading', () => {
    console.log('Ambient Light Level:', ambientLightSensor.illuminance);
  });

  ambientLightSensor.start();
} else {
  console.log('AmbientLightSensor is not supported on this device.');
}

DeviceMotion和DeviceOrientation

如果通用傳感器API不可用,可以使用DeviceMotion和DeviceOrientation事件來訪問設(shè)備的加速度計、陀螺儀和羅盤數(shù)據(jù)。

使用DeviceMotion事件獲取加速度計數(shù)據(jù):

window.addEventListener('devicemotion', (event) => {
  console.log('Acceleration X:', event.acceleration.x);
  console.log('Acceleration Y:', event.acceleration.y);
  console.log('Acceleration Z:', event.acceleration.z);

  console.log('Acceleration Including Gravity X:', event.accelerationIncludingGravity.x);
  console.log('Acceleration Including Gravity Y:', event.accelerationIncludingGravity.y);
  console.log('Acceleration Including Gravity Z:', event.accelerationIncludingGravity.z);
});

使用DeviceOrientation事件獲取陀螺儀和羅盤數(shù)據(jù):

window.addEventListener('deviceorientation', (event) => {
  console.log('Alpha:', event.alpha); // 繞Z軸旋轉(zhuǎn)(羅盤方向)
  console.log('Beta:', event.beta);   // 繞X軸旋轉(zhuǎn)(前后傾斜)
  console.log('Gamma:', event.gamma); // 繞Y軸旋轉(zhuǎn)(左右傾斜)
});

訪問 GPS 坐標

在 web 上可以使用 Geolocation API 獲取設(shè)備的當前地理位置(通常是經(jīng)緯度坐標)。

首先,網(wǎng)頁需要請求用戶的權(quán)限來獲取其地理位置。這是因為地理位置信息屬于用戶的隱私數(shù)據(jù),必須得到用戶的明確同意。一旦用戶授予權(quán)限,可以使用navigator.geolocation.getCurrentPosition()方法來獲取當前位置。這個方法接受兩個回調(diào)函數(shù)作為參數(shù):成功回調(diào)和失敗回調(diào)。

  • 成功回調(diào):當成功獲取到位置信息時調(diào)用,接收一個位置對象作為參數(shù)。
  • 失敗回調(diào):當獲取位置信息失敗時調(diào)用,接收一個錯誤對象作為參數(shù)。
// 請求用戶位置  
if (navigator.geolocation) {  
  navigator.geolocation.getCurrentPosition(successCallback, errorCallback);  
} else {  
  console.log("Geolocation is not supported by this browser.");  
}  
  
// 成功回調(diào)  
function successCallback(position) {  
  const latitude = position.coords.latitude;  
  const longitude = position.coords.longitude;  
  console.log(`Latitude: ${latitude}, Longitude: ${longitude}`);  
}  
  
// 失敗回調(diào)  
function errorCallback(error) {  
  switch(error.code) {  
    case error.PERMISSION_DENIED:  
      console.log("User denied the request for Geolocation.");  
      break;  
    case error.POSITION_UNAVAILABLE:  
      console.log("Location information is unavailable.");  
      break;  
    case error.TIMEOUT:  
      console.log("The request to get user location timed out.");  
      break;  
    case error.UNKNOWN_ERROR:  
      console.log("An unknown error occurred.");  
      break;  
  }  
}

檢查設(shè)備電池電量

使用Battery API確實可以獲取關(guān)于電池電量的信息,并且在電池電量或充電狀態(tài)發(fā)生變化時收到通知。

獲取電量信息

  1. 檢測瀏覽器支持
  • 在使用Battery API之前,開發(fā)者需要先檢測用戶所使用的瀏覽器是否支持該API。
  • 可以通過if ('getBattery' in navigator)來判斷瀏覽器是否支持Battery API。
  1. 獲取電池對象
  • 如果瀏覽器支持Battery API,可以通過調(diào)用navigator.getBattery()方法來獲取一個Promise對象。
  • 這個Promise對象在成功時會傳遞一個BatteryManager對象,該對象包含了電池的各種信息。
  1. 讀取電池信息
  • battery.level:表示當前電池的電量,范圍從0到1,可以通過乘以100來轉(zhuǎn)換為百分比形式。
  • battery.charging:一個布爾值,表示設(shè)備當前是否在充電。
  • battery.chargingTime:表示設(shè)備預(yù)計還需要多長時間充滿,單位為秒(如果設(shè)備已經(jīng)在充電且即將充滿,則可能為0或接近0)。
  • battery.dischargingTime:表示設(shè)備預(yù)計還能使用多長時間,單位為秒(如果設(shè)備正在放電且電量即將耗盡,則可能為一個較大的值或Infinity)。
  • 一旦獲取到BatteryManager對象,開發(fā)者就可以通過該對象的屬性和事件來獲取電池信息。
  • 主要的屬性包括:

電池、電量狀態(tài)通知

  1. 監(jiān)聽電池狀態(tài)變化
  • 為了更加精準地捕捉和響應(yīng)用戶設(shè)備的電池狀態(tài)動態(tài),開發(fā)者需要實時監(jiān)聽電池狀態(tài)的變化。
  • 可以通過為BatteryManager對象注冊事件監(jiān)聽器來實現(xiàn)這一功能。
  1. 事件類型
  • levelchange:當設(shè)備電量發(fā)生變化時觸發(fā)。
  • chargingchange:當設(shè)備的充電狀態(tài)發(fā)生變化時觸發(fā)(例如,從充電狀態(tài)變?yōu)槲闯潆姞顟B(tài),或反之)。
  • chargingtimechange:當設(shè)備充滿電所需時間發(fā)生變化時觸發(fā)(這通常發(fā)生在充電速率改變時)。
  • dischargingtimechange:當設(shè)備放空電所需時間發(fā)生變化時觸發(fā)(這通常發(fā)生在電池使用量或放電速率改變時)。
  1. 實現(xiàn)方式
  • 使用battery.addEventListener()方法來為上述事件類型注冊監(jiān)聽器。
  • 在監(jiān)聽器的回調(diào)函數(shù)中,可以更新UI或執(zhí)行其他邏輯來響應(yīng)電池狀態(tài)的變化。

以下是一個簡單的例子:

if ('getBattery' in navigator) {  
  navigator.getBattery().then(function(battery) {  
    // 初始獲取電池信息  
    console.log('當前電池電量: ' + battery.level * 100 + '%');  
    console.log('充電狀態(tài): ' + (battery.charging ? '正在充電' : '未充電'));  
    console.log('充滿電所需時間: ' + battery.chargingTime + '秒');  
    console.log('防空電所需時間: ' + battery.dischargingTime + '秒');  
  
    // 監(jiān)聽電池狀態(tài)變化  
    battery.addEventListener('levelchange', function() {  
      console.log('電量已更新: 當前電量為' + (battery.level * 100) + '%');  
    });  
  
    battery.addEventListener('chargingchange', function() {  
      console.log('充電狀態(tài)已變更: ' + (battery.charging ? '正在充電' : '未在充電'));  
    });  
  
    battery.addEventListener('chargingtimechange', function() {  
      console.log('充滿電所需時間更新: 剩余' + battery.chargingTime + '秒');  
    });  
  
    battery.addEventListener('dischargingtimechange', function() {  
      console.log('放空電所需時間更新: 剩余' + battery.dischargingTime + '秒');  
    });  
  }).catch(function(error) {  
    // 處理獲取電池對象失敗的情況  
    console.error('獲取電池信息失敗:', error);  
  });  
} else {  
  // 處理瀏覽器不支持Battery API的情況  
  console.log('當前瀏覽器不支持Battery API');  
}

本地網(wǎng)絡(luò)中的多媒體播放控制

Remote Playback API

Remote Playback API 允許網(wǎng)頁應(yīng)用將音頻和視頻內(nèi)容發(fā)送到遠程播放設(shè)備(如智能電視、無線音箱等)進行播放。這對于構(gòu)建家庭娛樂系統(tǒng)或跨設(shè)備媒體共享功能特別有用。

工作原理

  1. 檢測支持:首先,應(yīng)用需要檢測瀏覽器是否支持 Remote Playback API。
  2. 獲取可用設(shè)備:通過調(diào)用 navigator.mediaDevices.enumerateDevices() 并過濾出支持 Remote Playback 的設(shè)備,可以獲取到當前網(wǎng)絡(luò)中的可用設(shè)備列表。但請注意,Remote Playback API 并不直接提供設(shè)備枚舉功能;通常,設(shè)備發(fā)現(xiàn)是通過其他機制(如 UPnP、DLNA 等)或用戶選擇來實現(xiàn)的。
  3. 建立連接:一旦選擇了目標設(shè)備,應(yīng)用就可以通過 navigator.remotePlayback.requestRemotePlayback() 方法嘗試與該設(shè)備建立連接。
  4. 發(fā)送媒體:連接建立后,應(yīng)用可以開始將媒體內(nèi)容發(fā)送到遠程設(shè)備進行播放。

假設(shè)有一個網(wǎng)頁應(yīng)用,它允許用戶選擇并播放存儲在本地服務(wù)器上的視頻文件。該應(yīng)用可以使用 Remote Playback API 將所選視頻發(fā)送到用戶的智能電視進行播放。

// 偽代碼示例,具體實現(xiàn)可能因設(shè)備和瀏覽器而異  
if ('remotePlayback' in navigator.mediaDevices) {  
  // 假設(shè)已經(jīng)通過某種方式選擇了目標設(shè)備  
  const remoteDevice = selectedDevice;  
    
  navigator.mediaDevices.requestRemotePlayback(remoteDevice)  
    .then(remote => {  
      // 成功建立連接,開始播放媒體  
      const mediaElement = document.querySelector('video'); // 假設(shè)頁面上有一個 <video> 元素  
      remote.loadVideo(URL.createObjectURL(mediaElement.currentSrc));  
      remote.play();  
    })  
    .catch(error => {  
      // 處理連接失敗的情況  
      console.error('Remote playback failed:', error);  
    });  
} else {  
  console.log('Remote Playback API is not supported in this browser.');  
}

Presentation API

Presentation API 則用于在第二屏幕(如輔助屏幕、HDMI 連接的顯示屏、無線連接的智能電視等)上呈現(xiàn)網(wǎng)頁內(nèi)容。它允許開發(fā)者將網(wǎng)頁的一部分或全部內(nèi)容投影到另一個屏幕上,這對于會議演示、家庭娛樂等場景非常有用。

工作原理

  1. 檢測支持:首先,應(yīng)用需要檢測瀏覽器是否支持 Presentation API。
  2. 獲取可用屏幕:通過調(diào)用 navigator.presentation.getAvailability() 和 navigator.presentation.requestSession() 方法,應(yīng)用可以獲取到當前可用的第二屏幕列表,并請求與其中一個屏幕建立會話。
  3. 建立連接并發(fā)送內(nèi)容:一旦會話建立,應(yīng)用就可以開始將內(nèi)容發(fā)送到第二屏幕進行顯示。

假設(shè)有一個網(wǎng)頁應(yīng)用,它允許用戶將當前頁面或某個特定部分的內(nèi)容投影到連接在同一本地網(wǎng)絡(luò)上的智能電視上進行顯示。

if ('presentation' in navigator) {  
  navigator.presentation.getAvailability().then(availability => {  
    if (availability === 'available') {  
      // 請求與第二屏幕建立會話  
      navigator.presentation.requestSession().then(presentationSession => {  
        // 會話建立成功,開始發(fā)送內(nèi)容  
        // 假設(shè)我們有一個要投影的 <div> 元素  
        const contentToPresent = document.querySelector('#content-to-present');  
          
        // 創(chuàng)建一個新的 HTML 文檔,并將要投影的內(nèi)容添加到其中  
        const presentationDocument = presentationSession.urls[0]; // 獲取用于投影的 URL  
        const iframe = document.createElement('iframe');  
        iframe.src = presentationDocument;  
        iframe.onload = () => {  
          const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;  
          iframeDoc.open();  
          iframeDoc.write(`  
            <!DOCTYPE html>  
            <html>  
            <head><title>Presentation</title></head>  
            <body>${contentToPresent.innerHTML}</body>  
            </html>  
          `);  
          iframeDoc.close();  
        };  
          
        // 將 iframe 添加到當前頁面中(雖然實際上它不會在當前頁面顯示)  
        // 這是為了觸發(fā) onload 事件并加載投影內(nèi)容  
        document.body.appendChild(iframe);  
          
        // 稍后可以從 DOM 中移除 iframe,因為它不再需要  
        // document.body.removeChild(iframe);  
          
      }).catch(error => {  
        // 處理請求會話失敗的情況  
        console.error('Presentation session request failed:', error);  
      });  
    } else {  
      console.log('No second screens available.');  
    }  
  }).catch(error => {  
    // 處理獲取可用性失敗的情況  
    console.error('Presentation API availability check failed:', error);  
  });  
} else {  
  console.log('Presentation API is not supported in this browser.');  
}
責任編輯:姜華 來源: 前端充電寶
相關(guān)推薦

2024-03-22 15:32:21

機器學(xué)習(xí)算法

2010-08-10 17:01:48

FlexJavaScript

2023-12-05 07:45:35

SQL數(shù)據(jù)庫

2024-04-03 09:27:49

后端開發(fā)數(shù)據(jù)庫內(nèi)核

2009-12-16 11:11:44

HTML 5

2019-04-04 09:08:41

2011-09-02 14:59:15

2024-03-01 20:55:40

Pytorch張量Tensor

2025-01-20 08:00:00

圖像增強深度學(xué)習(xí)AI

2009-10-21 17:02:51

綜合布線施工經(jīng)驗

2009-12-07 09:39:04

Linux設(shè)備驅(qū)動硬件通信

2010-03-15 15:45:50

2023-01-03 17:31:52

2024-12-31 07:00:00

2013-01-09 10:34:13

OpenStackKVM

2009-12-16 15:59:13

Linux設(shè)備文件管理

2021-04-27 08:31:10

前端應(yīng)用場景

2021-12-29 09:00:36

Go文件syscall

2015-05-27 14:55:45

點贊
收藏

51CTO技術(shù)棧公眾號