You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tizen Studio开发HLS播放器打包上传后无限加载问题排查

问题

我在Tizen Studio中开发了一款基于hls.js的HLS流媒体播放器,支持遥控操作及其他附加功能。在Tizen Studio模拟器中测试时所有功能正常,但打包上传至三星卖家平台后,QA测试人员反馈播放器始终处于无限加载状态。请问可能的问题是什么?

核心代码(main.js)

var videoPlayer = document.getElementById("videoPlayer");
videoPlayer.tabIndex = 0; // add tabindex to focus the element
videoPlayer.requestFullscreen();

var player = new shaka.Player(videoPlayer);

player.configure({
  abr: {
    enabled: true
  }
});

var manifestUri = 'removed';

player.load(manifestUri).then(function() {
  console.log('The video has now been loaded!');
  videoPlayer.requestFullscreen();
}).catch(function(error) {
  console.error('Error code', error.code, 'object', error);
});

player.addEventListener('error', function(event) {
  console.error('Error code', event.detail.code, 'object', event.detail);
  console.log('A video playback error occurred.');
  if (event.detail.code === 6003 || event.detail.code === 6004 || event.detail.code === 6005) {
    console.log('The video failed to load due to a network error. Retrying...');
    showOfflineNotification();
    setTimeout(function() {
      player.load(manifestUri);
    }, 5000);
  }
});

function showOfflineNotification() {
  var offlineNotification = document.getElementById("offline-popup");
  offlineNotification.style.display = "block";
  videoPlayer.style.display = "none";
}

function showOnlineNotification() {
  var offlineNotification = document.getElementById("offline-popup");
  offlineNotification.style.display = "none";
  videoPlayer.style.display = "block";
  player.load(manifestUri).then(function() {
    console.log('The video has now been loaded!');
    videoPlayer.requestFullscreen();
  }).catch(function(error) {
    console.error('Error code', error.code, 'object', error);
  });
}

window.addEventListener("online", showOnlineNotification);
window.addEventListener("offline", showOfflineNotification);

if (navigator.onLine) {
  showOnlineNotification();
} else {
  showOfflineNotification();
}

// Add event listeners to the buttons
var playButton = document.getElementById("playButton");
var pauseButton = document.getElementById("pauseButton");
var stopButton = document.getElementById("stopButton");
var forwardButton = document.getElementById("forwardButton");
var backwardButton = document.getElementById("backwardButton");

playButton.addEventListener("click", function() {
  player.play();
});

pauseButton.addEventListener("click", function() {
  player.pause();
});

stopButton.addEventListener("click", function() {
  player.pause();
  player.seek(0);
});

forwardButton.addEventListener("click", function() {
  var currentTime = player.getPlaybackRate();
  player.seek(currentTime + 10);
});

backwardButton.addEventListener("click", function() {
  var currentTime = player.getPlaybackRate();
  player.seek(currentTime - 10);
});

//Register listeners for remote control buttons
tizen.tvinputdevice.registerKey("MediaPlay", function() {
  player.play();
});

tizen.tvinputdevice.registerKey("MediaPause", function() {
  player.pause();
});

tizen.tvinputdevice.registerKey("MediaStop", function() {
  player.pause();
  player.seek(0);
});

tizen.tvinputdevice.registerKey("MediaFastForward", function() {
  var currentTime = player.getPlaybackRate();
  player.seek(currentTime + 10);
});

tizen.tvinputdevice.registerKey("MediaRewind", function() {
  var currentTime = player.getPlaybackRate();
  player.seek(currentTime - 10);
});

//Add event listener to handle keyboard controls
document.addEventListener("keydown", function(event) {
  if (event.target !== videoPlayer) return; // check if videoPlayer has focus
  switch (event.keyCode) {
    case 10009: // Return key
      window.history.back();
      break;
    case 415: // Play key
      if (player.isPaused()) {
        player.play();
      } else {
        player.pause();
      }
      break;
    case 413: // Stop key
      player.pause();
      player.seek(0);
      break;
    case 417: // Forward key
      var currentTime = player.getPlaybackRate();
      player.seek(currentTime + 10);
      break;
    case 412: // Backward key
      var currentTime = player.getPlaybackRate();
      player.seek(currentTime - 10);
      break;
    default:
      console.log("Unsupported key: " + event.keyCode);
  }
});
});
可能的问题分析
  • 权限配置缺失
    三星TV应用必须在tizen-manifest.xml中声明http://tizen.org/privilege/internet网络权限,否则真机无法访问HLS流。模拟器默认放宽权限限制,导致测试正常但真机失败。若使用HTTPS流,还需确认添加http://tizen.org/privilege/network.get权限及正确配置证书白名单。

  • HLS流兼容性问题
    部分三星TV型号对HLS编码、码率、分段设置有严格要求:必须使用H.264/AAC编码,分段时长建议2-10秒,加密流需符合三星DRM规范。模拟器支持更多兼容模式,但真机仅适配符合规范的流。

  • 初始化时机错误
    代码直接在全局作用域初始化播放器,但Tizen应用需等待DOMContentLoaded或tizenhwkey事件触发后再执行设备相关操作。真机环境下DOM或Tizen API加载较慢,提前初始化会导致播放器启动失败。另外代码末尾多余的});会引发语法错误,真机环境会严格执行导致功能失效。

  • 全屏API限制
    三星平台限制自动全屏操作,代码中多次调用videoPlayer.requestFullscreen()未通过用户交互触发(如首次播放前需遥控/点击操作),导致播放器无法正常初始化。

  • 网络状态检测逻辑缺陷
    navigator.onLine在Tizen真机环境下可能延迟或不准确,若误判离线状态会触发showOfflineNotification隐藏视频元素。同时showOnlineNotification重复调用player.load(manifestUri)会导致请求冲突,阻塞加载流程。

  • 遥控按键注册错误
    tizen.tvinputdevice.registerKey的第二个参数应为事件名而非匿名函数,错误的注册方式会导致API调用失败,影响播放器正常流程。正确写法应为先注册按键,再通过keydown事件监听按键操作:

    tizen.tvinputdevice.registerKey("MediaPlay");
    document.addEventListener("keydown", function(event) {
      if (event.keyName === "MediaPlay") {
        player.play();
      }
    });
    

内容的提问来源于stack exchange,提问作者Sloobotv2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 21:45:01