<template>
  <view class="native-rtsp-player" :style="containerStyle">
    <!-- 视频信息标题（可选） -->
    <view v-if="showHeader" class="header">
      <view class="back-button" v-if="showBackButton" @click="$emit('back')">
        <u-icon name="arrow-left" color="#FFFFFF" size="32"></u-icon>
      </view>
      <view class="title">{{ videoTitle }}</view>
    </view>
    
    <!-- 视频播放区域 -->
    <view class="video-container" :style="{ height: videoHeight }">
      <!-- #ifdef APP-PLUS -->
      <video 
        :id="videoId" 
        class="video-player" 
        :src="playUrl" 
        :autoplay="autoplay" 
        :controls="showNativeControls"
        :muted="isMuted"
        :show-center-play-btn="showCenterPlayBtn"
        :show-fullscreen-btn="showFullscreenBtn"
        @error="onVideoError"
        @timeupdate="onTimeUpdate"
        @loadedmetadata="onLoadedMetadata"
        @ended="onVideoEnded"
        @play="onPlay"
        @pause="onPause"
      ></video>
      <!-- #endif -->
      
      <!-- #ifndef APP-PLUS -->
      <view class="h5-notice">
        <u-icon name="warning-circle" color="#FF6B6B" size="60"></u-icon>
        <text class="notice-text">H5环境不支持原生RTSP播放</text>
        <text class="notice-subtext">请在APP环境中使用</text>
      </view>
      <!-- #endif -->
    </view>
    
    <!-- 自定义控制按钮区域（可选） -->
    <view v-if="showCustomControls" class="controls-container">
      <view class="control-buttons">
        <view class="control-btn" @click="togglePlayPause">
          <u-icon :name="isPlaying ? 'pause' : 'play'" color="#498CEC" size="48"></u-icon>
          <text class="btn-text">{{ isPlaying ? '暂停' : '播放' }}</text>
        </view>
        
        <view class="control-btn" @click="toggleMute">
          <u-icon :name="isMuted ? 'volume-mute' : 'volume-medium'" color="#498CEC" size="48"></u-icon>
          <text class="btn-text">{{ isMuted ? '静音' : '有声' }}</text>
        </view>
        
        <view class="control-btn" @click="toggleFullscreen">
          <u-icon name="expand" color="#498CEC" size="48"></u-icon>
          <text class="btn-text">全屏</text>
        </view>
      </view>
      
      <!-- 播放进度 -->
      <view class="progress-container" v-if="duration > 0">
        <text class="time-text">{{ formatTime(currentTime) }}</text>
        <slider 
          v-model="progressValue" 
          class="slider" 
          activeColor="#498CEC" 
          backgroundColor="#E0E0E0" 
          blockColor="#498CEC" 
          block-size="20"
          @change="onProgressChange"
        />
        <text class="time-text">{{ formatTime(duration) }}</text>
      </view>
    </view>
    
    <!-- 加载提示 -->
    <u-loading-page v-if="isLoading && showLoading" :loading-text="loadingText"></u-loading-page>
    
    <!-- 错误提示 -->
    <u-modal v-if="showErrorModal" v-model="showError" title="播放错误" :content="errorMessage" :show-cancel-button="false" confirm-text="确定"></u-modal>
  </view>
</template>

<script>
import { isString } from '@/utils/tool';
import uView from '@/uview-ui';

export default {
  name: 'NativeRtspPlayer',
  components: {
    ...uView
  },
  props: {
    // RTSP流地址（必填）
    rtspUrl: {
      type: String,
      required: true,
      default: ''
    },
    // 视频信息对象
    videoInfo: {
      type: Object,
      default: () => ({})
    },
    // 视频标题
    title: {
      type: String,
      default: ''
    },
    // 视频容器高度
    height: {
      type: [String, Number],
      default: '500rpx'
    },
    // 是否自动播放
    autoplay: {
      type: Boolean,
      default: true
    },
    // 是否显示原生控件
    showNativeControls: {
      type: Boolean,
      default: true
    },
    // 是否显示自定义控件
    showCustomControls: {
      type: Boolean,
      default: true
    },
    // 是否显示加载提示
    showLoading: {
      type: Boolean,
      default: true
    },
    // 是否显示错误弹窗
    showErrorModal: {
      type: Boolean,
      default: true
    },
    // 是否显示头部
    showHeader: {
      type: Boolean,
      default: true
    },
    // 是否显示返回按钮
    showBackButton: {
      type: Boolean,
      default: true
    },
    // 是否显示中心播放按钮
    showCenterPlayBtn: {
      type: Boolean,
      default: true
    },
    // 是否显示全屏按钮
    showFullscreenBtn: {
      type: Boolean,
      default: true
    },
    // 最大重试次数
    maxRetryCount: {
      type: Number,
      default: 3
    },
    // 重试延迟时间（毫秒）
    retryDelay: {
      type: Number,
      default: 2000
    },
    // 容器样式
    containerStyle: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
      return {
        // 处理后的播放地址
        playUrl: '',
        videoHeight: this.height,
        
        // 播放状态
        isPlaying: this.autoplay,
        isMuted: false,
        currentTime: 0,
        duration: 0,
        progressValue: 0,
        isFullscreen: false,
        
        // 加载和错误状态
        isLoading: this.autoplay,
        loadingText: '正在加载视频...',
        showError: false,
        errorMessage: '',
        
        // 重试相关
        retryCount: 0,
        
        // 平台信息
        platform: '',
        isIOS: false,
        isAndroid: false,
        
        // 定时器
        retryTimer: null,
        
        // 视频ID（用于创建唯一的视频上下文）
        videoId: `rtsp-video-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
        
        // 音频上下文
        audioContext: null,
        useSeparateAudio: false, // 是否使用独立音频播放
        
        // 音频轨道检测
        hasAudioTrack: false, // RTSP流是否包含音频轨道
        isAudioDetected: false // 是否已完成音频轨道检测
      };
    },
  computed: {
    // 计算视频标题
    videoTitle() {
      if (this.title) return this.title;
      if (this.videoInfo && this.videoInfo.videoName) return this.videoInfo.videoName;
      return 'RTSP视频播放';
    }
  },
  
  watch: {
    // 监听RTSP地址变化
    rtspUrl: {
      handler(newVal) {
        if (newVal) {
          this.initPlayer();
        }
      },
      immediate: true
    },
    
    // 监听高度变化
    height(newVal) {
      this.videoHeight = newVal;
    }
  },
  
  mounted() {
    // 初始化平台信息
    this.initPlatformInfo();
    
    // 延迟初始化播放器，确保DOM已渲染
    this.$nextTick(() => {
      if (this.rtspUrl && this.autoplay) {
        this.initPlayer();
      }
    });
  },
  
  beforeUnmount() {
    // 清理资源
    this.cleanupResources();
  },
  
  methods: {
	/**
     * 停用音频会话（暂停时使用）
     */
    deactivateAudioSession() {
      try {
        if (!this.isIOS || typeof window === 'undefined' || typeof window.plus === 'undefined' || typeof window.plus.ios === 'undefined') {
          return;
        }
        
        const AVAudioSession = window.plus.ios.import('AVAudioSession');
        if (AVAudioSession && typeof AVAudioSession.sharedInstance === 'function') {
          const session = AVAudioSession.sharedInstance();
          if (session && typeof session.setActive === 'function') {
            try {
              session.setActive(false);
              console.log('音频会话已停用');
            } catch (e) {
              console.warn('停用音频会话失败:', e);
            }
          }
          
          // 释放资源
          if (typeof window.plus.ios.deleteObject === 'function') {
            window.plus.ios.deleteObject(session);
          }
        }
      } catch (error) {
        console.warn('停用音频会话时发生错误:', error);
      }
    },
    /**
     * 初始化平台信息
     */
    initPlatformInfo() {
      try {
        const systemInfo = uni.getSystemInfoSync();
        this.platform = systemInfo.platform;
        this.isIOS = systemInfo.platform === 'ios';
        this.isAndroid = systemInfo.platform === 'android';
      } catch (error) {
        console.error('获取系统信息失败:', error);
      }
    },
    
    /**
     * 设置视频容器高度
     */
    setVideoHeight() {
      try {
        const systemInfo = uni.getSystemInfoSync();
        const windowHeight = systemInfo.windowHeight;
        // 视频高度设为屏幕高度的50%
        this.videoHeight = `${windowHeight * 0.5}px`;
      } catch (error) {
        console.error('设置视频高度失败:', error);
      }
    },
    
    /**
     * 初始化播放器
     */
    initPlayer() {
      // #ifdef APP-PLUS
      this.isLoading = true;
      
      // 根据平台处理RTSP地址
      this.processRtspUrl();
      
      // 延迟执行以确保video组件已渲染
      setTimeout(() => {
        this.startPlayback();
      }, 500);
      // #endif
      
      // #ifndef APP-PLUS
      this.handleError('H5环境不支持原生RTSP播放');
      // #endif
    },
    
    /**
     * 处理RTSP地址
     */
    processRtspUrl() {
      // 对于iOS，某些原生播放器可能需要特殊处理
      // 这里根据实际情况调整URL格式
      if (this.isIOS) {
        // iOS平台处理逻辑
        // 某些情况下可能需要使用第三方原生插件来播放RTSP
        // 这里假设直接使用video标签可以播放RTSP
        this.playUrl = this.rtspUrl;
      } else if (this.isAndroid) {
        // Android平台处理逻辑
        this.playUrl = this.rtspUrl;
      } else {
        // 其他平台
        this.playUrl = this.rtspUrl;
      }
      
      // 如果音频上下文已初始化，更新音频源
      if (this.useSeparateAudio && this.audioContext) {
        this.setAudioSource(this.playUrl);
      }
    },
    
    /**
     * 开始播放
     */
    startPlayback() {
      // #ifdef APP-PLUS
      try {
        // 对于iOS，先确保音频会话已激活，再播放视频
        if (this.isIOS) {
          // 先尝试激活音频会话（用户交互时）
          this.setupiOSAudio();
          
          // 额外尝试：在iOS上，有时需要显式请求音频播放权限
          try {
            if (typeof window !== 'undefined' && typeof window.plus !== 'undefined' && typeof window.plus.device !== 'undefined') {
              // 获取设备信息，确认iOS版本
              const device = window.plus.device;
              const osInfo = device.osInfo || {};
              console.log('设备信息:', { platform: device.platform, version: osInfo.version });
            }
          } catch (e) {
            console.warn('获取设备信息失败:', e);
          }
        }
        
        const videoContext = uni.createVideoContext(this.videoId, this);
        
        // 播放视频
        videoContext.play();
        this.isPlaying = true;
        this.$emit('play');
        
        // 延迟尝试再次激活音频会话（iOS上有时需要在播放后再次激活）
        if (this.isIOS) {
          setTimeout(() => {
            try {
              this.ensureAudioActive();
            } catch (e) {
              console.warn('延迟激活音频失败:', e);
            }
          }, 500);
        }
        
        // 5秒后如果还在加载，显示重试选项
        setTimeout(() => {
          if (this.isLoading) {
            this.loadingText = '加载中，请稍候...';
          }
        }, 5000);
        
      } catch (error) {
        console.error('开始播放失败:', error);
        this.handlePlaybackError(error);
      }
      // #endif
    },
    
    /**
     * 确保音频会话处于激活状态
     * 用于在视频播放后再次尝试激活音频，提高iOS设备上RTSP流音频播放成功率
     */
    ensureAudioActive() {
      try {
        if (!this.isIOS || typeof window === 'undefined' || typeof window.plus === 'undefined' || typeof window.plus.ios === 'undefined') {
          return;
        }
        
        const AVAudioSession = window.plus.ios.import('AVAudioSession');
        if (AVAudioSession && typeof AVAudioSession.sharedInstance === 'function') {
          const session = AVAudioSession.sharedInstance();
          if (session && typeof session.setActive === 'function') {
            try {
              // 先停用再重新激活，有时能解决音频问题
              session.setActive(false);
              session.setActive(true);
              console.log('音频会话重新激活成功');
            } catch (e) {
              console.warn('重新激活音频会话失败:', e);
            }
          }
          
          // 释放资源
          if (typeof window.plus.ios.deleteObject === 'function') {
            window.plus.ios.deleteObject(session);
          }
        }
      } catch (error) {
        console.warn('确保音频激活时发生错误:', error);
      }
    },
    
    /**
     * 初始化音频上下文
     */
    initAudioContext() {
      try {
        // 安全检查
        if (typeof uni === 'undefined' || typeof uni.createInnerAudioContext !== 'function') {
          console.warn('当前环境不支持createInnerAudioContext');
          return false;
        }
        
        // 创建独立音频上下文
        this.audioContext = uni.createInnerAudioContext();
        
        // 安全地设置可能的可写属性，避免修改只读属性
        try {
          // 只尝试设置可能可写的属性
          if (typeof this.audioContext.setAutoplay === 'function') {
            this.audioContext.setAutoplay(false);
          } else if (Object.getOwnPropertyDescriptor(this.audioContext, 'autoplay')?.writable) {
            this.audioContext.autoplay = false;
          }
        } catch (e) {
          console.warn('设置autoplay属性失败，跳过:', e);
        }
        
        try {
          if (typeof this.audioContext.setObeyMuteSwitch === 'function') {
            this.audioContext.setObeyMuteSwitch(false);
          } else if (Object.getOwnPropertyDescriptor(this.audioContext, 'obeyMuteSwitch')?.writable) {
            this.audioContext.obeyMuteSwitch = false;
          }
        } catch (e) {
          console.warn('设置obeyMuteSwitch属性失败，跳过:', e);
        }
        
        // 安全地添加事件监听器
        try {
          if (typeof this.audioContext.onPlay === 'function') {
            this.audioContext.onPlay(() => {
              console.log('音频开始播放');
            });
          }
        } catch (e) {
          console.warn('添加onPlay监听器失败，跳过:', e);
        }
        
        try {
          if (typeof this.audioContext.onPause === 'function') {
            this.audioContext.onPause(() => {
              console.log('音频暂停');
            });
          }
        } catch (e) {
          console.warn('添加onPause监听器失败，跳过:', e);
        }
        
        try {
          if (typeof this.audioContext.onError === 'function') {
            this.audioContext.onError((res) => {
              console.warn('音频播放错误:', res);
              // 音频错误不应影响视频播放
            });
          }
        } catch (e) {
          console.warn('添加onError监听器失败，跳过:', e);
        }
        
        console.log('音频上下文初始化成功');
        return true;
      } catch (error) {
        console.warn('初始化音频上下文失败:', error);
        this.audioContext = null;
        return false;
      }
    },
    
    /**
     * 设置音频源
     */
    setAudioSource(url) {
      try {
        if (this.audioContext && url) {
          try {
            // 安全地设置音频源
            if (typeof this.audioContext.src === 'string' || Object.getOwnPropertyDescriptor(this.audioContext, 'src')?.writable) {
              this.audioContext.src = url;
              console.log('音频源设置成功:', url);
              return true;
            }
          } catch (e) {
            console.warn('设置音频源失败:', e);
          }
        }
        return false;
      } catch (error) {
        console.warn('设置音频源时发生错误:', error);
        return false;
      }
    },
    
    /**
     * iOS音频设置
     */
    setupiOSAudio() {
      try {
        // 尝试初始化独立音频上下文
        this.useSeparateAudio = this.initAudioContext();
        
        if (this.useSeparateAudio) {
          console.log('将使用createInnerAudioContext处理音频');
          // 尝试设置音频源
          if (this.playUrl) {
            this.setAudioSource(this.playUrl);
          }
        } else {
          // 安全检查：确保只在APP-PLUS环境下执行，避免在浏览器中报错
          const isPlusEnv = typeof window !== 'undefined' && typeof window.plus !== 'undefined';
          
          if (!isPlusEnv) {
            console.log('非APP环境，跳过音频设置');
            return;
          }
          
          // 尝试不同的音频设置方法，优雅降级
          try {
            // 方案1: 尝试使用plus.audio API（如果可用）
            if (typeof plus.audio !== 'undefined' && typeof plus.audio.createAudioContext === 'function') {
              try {
                const audioContext = plus.audio.createAudioContext();
                if (audioContext && typeof audioContext.play === 'function') {
                  console.log('尝试使用plus.audio API');
                }
              } catch (e) {
                console.warn('创建音频上下文失败:', e);
              }
            }
          } catch (e1) {
            console.warn('plus.audio API操作失败:', e1);
          }
          
          try {
            // 方案2: 尝试使用AVAudioSession（如果可用）
            if (typeof plus.ios !== 'undefined' && typeof plus.ios.import === 'function') {
              try {
                const AVAudioSession = plus.ios.import('AVAudioSession');
                if (AVAudioSession && typeof AVAudioSession.sharedInstance === 'function') {
                  const session = AVAudioSession.sharedInstance();
                  
                  // 先尝试设置音频会话类别 - 这是iOS上音频播放的关键
                  if (session && typeof session.setCategory === 'function') {
                    try {
                      // 对于视频播放，使用playback类别
                      // 尝试不同的类别设置方式
                      try {
                        // iOS 10+ 推荐方式
                        const CategoryPlayback = plus.ios.newString('AVAudioSessionCategoryPlayback');
                        const ModeDefault = plus.ios.newString('AVAudioSessionModeDefault');
                        const options = 1; // AVAudioSessionCategoryOptionMixWithOthers
                        session.setCategory_withMode_options_(CategoryPlayback, ModeDefault, options);
                        console.log('AVAudioSession类别设置成功(10+)');
                        plus.ios.deleteObject(CategoryPlayback);
                        plus.ios.deleteObject(ModeDefault);
                      } catch (catError) {
                        console.warn('设置音频会话类别(10+)失败，尝试旧方式:', catError);
                        // 尝试旧版API
                        try {
                          const CategoryPlayback = plus.ios.newString('AVAudioSessionCategoryPlayback');
                          session.setCategory_(CategoryPlayback);
                          console.log('AVAudioSession类别设置成功(旧版)');
                          plus.ios.deleteObject(CategoryPlayback);
                        } catch (oldError) {
                          console.warn('设置音频会话类别(旧版)失败:', oldError);
                        }
                      }
                    } catch (e) {
                      console.warn('设置音频会话类别失败:', e);
                    }
                  }
                  
                  // 然后激活音频会话
                  if (session && typeof session.setActive === 'function') {
                    try {
                      // 尝试以不同的方式激活
                      try {
                        // iOS 6+ 方式
                        session.setActive_withOptions_(true, 1); // 1 = AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
                        console.log('AVAudioSession激活成功(带选项)');
                      } catch (activeError) {
                        console.warn('激活音频会话(带选项)失败，尝试简单方式:', activeError);
                        // 尝试简单激活
                        session.setActive(true);
                        console.log('AVAudioSession激活成功(简单方式)');
                      }
                    } catch (e) {
                      console.warn('激活音频会话失败:', e);
                    }
                  }
                  
                  // 检查音频会话状态
                  if (session && typeof session.category === 'function') {
                    try {
                      const category = session.category();
                      console.log('当前音频会话类别:', category);
                    } catch (e) {
                      console.warn('获取音频会话类别失败:', e);
                    }
                  }
                  
                  // 释放资源
                  if (typeof plus.ios.deleteObject === 'function') {
                    plus.ios.deleteObject(session);
                  }
                }
              } catch (e) {
                console.warn('AVAudioSession操作失败:', e);
              }
            }
          } catch (e2) {
            console.warn('AVAudioSession相关操作失败:', e2);
          }
        }
        
        console.log('音频设置完成');
      } catch (error) {
        console.warn('音频设置失败，将继续播放视频:', error);
        // 即使音频设置失败，也不阻止视频播放
      }
    },
    
    /**
     * 切换播放/暂停
     */
    togglePlayPause() {
      try {
        const videoContext = uni.createVideoContext(this.videoId, this);
        if (this.isPlaying) {
          // 暂停视频
          videoContext.pause();
          
          // 暂停独立音频（如果启用）
          if (this.useSeparateAudio && this.audioContext && typeof this.audioContext.pause === 'function') {
            try {
              this.audioContext.pause();
              console.log('音频已暂停');
            } catch (e) {
              console.warn('暂停独立音频失败:', e);
            }
          }
          
          // iOS平台暂停时的处理
          if (this.isIOS) {
            try {
              // 可以选择在这里暂停后暂时关闭音频会话，节省资源
              this.deactivateAudioSession();
            } catch (e) {
              console.warn('停用音频会话失败:', e);
            }
          }
          
          this.$emit('pause');
        } else {
          // iOS平台播放前再次确保音频会话激活
          if (this.isIOS) {
            try {
              this.setupiOSAudio();
              console.log('播放前重新设置音频会话');
            } catch (e) {
              console.warn('播放前设置音频失败:', e);
            }
          }
          
          // 播放视频
          videoContext.play();
          
          // 播放独立音频（如果启用）
          if (this.useSeparateAudio && this.audioContext && typeof this.audioContext.play === 'function') {
            try {
              // 确保音频源已设置
              if (!this.audioContext.src || this.audioContext.src !== this.playUrl) {
                this.setAudioSource(this.playUrl);
              }
              // 播放音频
              this.audioContext.play();
              console.log('音频开始播放');
            } catch (e) {
              console.warn('播放独立音频失败:', e);
            }
          }
          
          this.$emit('play');
        }
        this.isPlaying = !this.isPlaying;
      } catch (error) {
        console.error('切换播放状态失败:', error);
        this.handleError('控制播放失败');
      }
    },
    
    /**
     * 切换静音状态
     */
    toggleMute() {
      try {
        const newMuteState = !this.isMuted;
        
        // 优先使用独立音频上下文（如果启用）
        if (this.useSeparateAudio && this.audioContext) {
          try {
            this.audioContext.volume = newMuteState ? 0 : 1;
            this.isMuted = newMuteState;
            this.$emit('volume-change', newMuteState ? 0 : 1);
            console.log('使用独立音频上下文切换静音状态');
            return;
          } catch (e) {
            console.warn('独立音频上下文操作失败:', e);
          }
        }
        
        // 回退到视频上下文控制
        const videoContext = uni.createVideoContext(this.videoId, this);
        
        // 方法1: 尝试使用setVolume（如果可用）
        if (videoContext && typeof videoContext.setVolume === 'function') {
          try {
            videoContext.setVolume(newMuteState ? 0.0 : 1.0);
            this.isMuted = newMuteState;
            this.$emit('volume-change', newMuteState ? 0 : 1);
            return;
          } catch (e) {
            console.warn('setVolume方法调用失败，尝试替代方案:', e);
          }
        }
        
        // 方法2: 尝试使用HTML5标准的muted属性（通过DOM操作）
        try {
          const videoElement = document.getElementById(this.videoId);
          if (videoElement) {
            videoElement.muted = newMuteState;
            this.isMuted = newMuteState;
            this.$emit('volume-change', newMuteState ? 0 : 1);
            console.log('使用DOM muted属性切换静音状态');
            return;
          }
        } catch (e) {
          console.warn('DOM操作失败，静默状态更新但可能未应用:', e);
        }
        
        // 方法3: 至少更新内部状态，确保UI一致性
        this.isMuted = newMuteState;
        this.$emit('volume-change', newMuteState ? 0 : 1);
        console.log('仅更新内部静音状态');
        
      } catch (error) {
        console.warn('切换静音状态时发生错误:', error);
        // 即使出错也更新内部状态，保持UI响应性
        this.isMuted = !this.isMuted;
        this.$emit('volume-change', this.isMuted ? 0 : 1);
      }
    },
    
    /**
     * 切换全屏
     */
    toggleFullscreen() {
      try {
        const videoContext = uni.createVideoContext(this.videoId, this);
        if (this.isFullscreen) {
          videoContext.exitFullScreen();
          this.$emit('fullscreen-change', false);
        } else {
          videoContext.requestFullScreen({ direction: 90 });
          this.$emit('fullscreen-change', true);
        }
        this.isFullscreen = !this.isFullscreen;
      } catch (error) {
        console.error('切换全屏失败:', error);
      }
    },
    
    /**
     * 处理进度条变化
     */
    onProgressChange(e) {
      try {
        const value = e.detail.value;
        const seekTime = (value / 100) * this.duration;
        
        const videoContext = uni.createVideoContext(this.videoId, this);
        videoContext.seek(seekTime);
        
        this.currentTime = seekTime;
        this.progressValue = value;
        this.$emit('seek', seekTime);
      } catch (error) {
        console.error('进度调整失败:', error);
      }
    },
    
    /**
     * 格式化时间
     */
    formatTime(seconds) {
      if (!seconds || isNaN(seconds)) return '00:00';
      
      const mins = Math.floor(seconds / 60);
      const secs = Math.floor(seconds % 60);
      
      return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    },
    
    /**
     * 视频错误回调
     */
    onVideoError(e) {
      console.error('视频播放错误:', e);
      this.handlePlaybackError(e);
    },
    
    /**
     * 视频时间更新回调
     */
    onTimeUpdate(e) {
      this.currentTime = e.detail.currentTime || 0;
      if (this.duration > 0) {
        this.progressValue = (this.currentTime / this.duration) * 100;
      }
      
      // 视频开始播放后关闭加载提示
      if (this.isLoading) {
        this.isLoading = false;
      }
    },
    
    /**
     * 视频元数据加载完成回调
     */
    onLoadedMetadata(e) {
      this.duration = e.detail.duration || 0;
      this.isLoading = false;
      
      // 尝试检测音频轨道
      this.detectAudioTrack();
    },
    
    /**
     * 检测RTSP流是否包含音频轨道
     * 此方法使用多种策略尝试确定当前视频流是否包含音频
     */
    detectAudioTrack() {
      try {
        // 策略1: 尝试通过DOM元素获取音频相关属性
        try {
          const videoElement = document.getElementById(this.videoId);
          if (videoElement) {
            // 检查是否有音频轨道
            if (videoElement.audioTracks && videoElement.audioTracks.length > 0) {
              this.hasAudioTrack = true;
              this.isAudioDetected = true;
              console.log('通过audioTracks检测到音频轨道');
              this.$emit('audio-detected', true);
              return true;
            }
            
            // 检查是否有音视频轨道（一些浏览器可能使用不同的API）
            if (videoElement.textTracks && videoElement.textTracks.length > 0) {
              // 这不是确定的音频检测方法，但可以作为参考
              console.log('检测到媒体轨道，但不确定是否为音频');
            }
          }
        } catch (domError) {
          console.warn('DOM音频检测失败:', domError);
        }
        
        // 策略2: 尝试通过独立音频上下文检测
        if (this.useSeparateAudio && this.audioContext && this.playUrl) {
          try {
            // 临时创建一个音频上下文进行测试
            const testAudio = uni.createInnerAudioContext();
            
            // 监听加载成功事件
            const onLoadSuccess = () => {
              // 音频能够加载通常意味着有音频轨道
              this.hasAudioTrack = true;
              this.isAudioDetected = true;
              console.log('通过音频上下文加载检测到音频');
              this.$emit('audio-detected', true);
              
              // 清理测试音频上下文
              try {
                testAudio.offLoad();
                testAudio.offError();
                testAudio.stop();
                if (typeof testAudio.destroy === 'function') {
                  testAudio.destroy();
                }
              } catch (cleanupError) {
                console.warn('清理测试音频上下文失败:', cleanupError);
              }
            };
            
            // 监听错误事件
            const onLoadError = () => {
              // 加载失败可能意味着没有音频轨道或格式不支持
              this.hasAudioTrack = false;
              this.isAudioDetected = true;
              console.log('音频上下文加载失败，可能没有音频轨道');
              this.$emit('audio-detected', false);
              
              // 清理测试音频上下文
              try {
                testAudio.offLoad();
                testAudio.offError();
                testAudio.stop();
                if (typeof testAudio.destroy === 'function') {
                  testAudio.destroy();
                }
              } catch (cleanupError) {
                console.warn('清理测试音频上下文失败:', cleanupError);
              }
            };
            
            testAudio.onLoad(onLoadSuccess);
            testAudio.onError(onLoadError);
            
            // 设置源并尝试加载
            testAudio.src = this.playUrl;
            
            // 5秒后超时处理
            setTimeout(() => {
              if (!this.isAudioDetected) {
                console.warn('音频检测超时');
                this.isAudioDetected = true;
                this.$emit('audio-detected', false);
                
                try {
                  testAudio.offLoad();
                  testAudio.offError();
                  testAudio.stop();
                  if (typeof testAudio.destroy === 'function') {
                    testAudio.destroy();
                  }
                } catch (cleanupError) {
                  console.warn('清理超时测试音频上下文失败:', cleanupError);
                }
              }
            }, 5000);
          } catch (audioError) {
            console.warn('独立音频上下文检测失败:', audioError);
          }
        }
        
        // 策略3: 尝试通过视频上下文检测
        try {
          const videoContext = uni.createVideoContext(this.videoId, this);
          // 在某些环境中，视频上下文可能有获取音频状态的方法
          if (typeof videoContext.getAudioTracks === 'function') {
            const tracks = videoContext.getAudioTracks();
            if (tracks && tracks.length > 0) {
              this.hasAudioTrack = true;
              this.isAudioDetected = true;
              console.log('通过视频上下文getAudioTracks检测到音频轨道');
              this.$emit('audio-detected', true);
              return true;
            }
          }
        } catch (videoContextError) {
          console.warn('视频上下文音频检测失败:', videoContextError);
        }
        
        // 如果所有检测策略都失败或未完成，设置为未检测到音频
        if (!this.isAudioDetected) {
          // 注意：这只是默认值，实际可能有音频但我们无法检测到
          console.log('无法确定是否包含音频轨道，默认为false');
        }
        
        return this.hasAudioTrack;
      } catch (error) {
        console.warn('检测音频轨道时发生错误:', error);
        return false;
      }
    },
    
    /**
     * 获取当前RTSP流的音频支持状态
     * 此方法可以被父组件调用，用于查询音频支持情况
     * @returns {Object} 包含音频状态信息的对象
     */
    getAudioStatus() {
      return {
        hasAudio: this.hasAudioTrack,
        detected: this.isAudioDetected,
        usingSeparateAudio: this.useSeparateAudio
      };
    },
    
    /**
     * 重新检测音频轨道
     * 强制重新执行音频检测逻辑
     * @returns {Promise<boolean>} 表示检测结果的Promise
     */
    reDetectAudioTrack() {
      return new Promise((resolve) => {
        try {
          // 重置检测状态
          this.hasAudioTrack = false;
          this.isAudioDetected = false;
          
          // 移除之前的监听器，避免多次触发
          this.$off('audio-detected');
          
          // 添加新的监听器来返回结果
          this.$once('audio-detected', (hasAudio) => {
            resolve(hasAudio);
          });
          
          // 执行检测
          this.detectAudioTrack();
          
          // 设置30秒超时
          setTimeout(() => {
            if (!this.isAudioDetected) {
              console.warn('重新检测音频超时，返回false');
              this.isAudioDetected = true;
              resolve(false);
            }
          }, 30000);
        } catch (error) {
          console.error('重新检测音频失败:', error);
          resolve(false);
        }
      });
    },
    
    /**
     * 视频播放结束回调
     */
    onVideoEnded() {
      this.isPlaying = false;
      this.$emit('ended');
      // 直播流可能不会触发此事件
    },
    
    /**
     * 视频开始播放回调
     */
    onPlay() {
      this.isPlaying = true;
      this.$emit('play');
    },
    
    /**
     * 视频暂停回调
     */
    onPause() {
      this.isPlaying = false;
      this.$emit('pause');
    },
    
    /**
     * 处理播放错误
     */
    handlePlaybackError(error) {
      this.isLoading = false;
      
      // 重试逻辑
      if (this.retryCount < this.maxRetryCount) {
        this.retryCount++;
        this.loadingText = `连接失败，${this.retryCount}/${this.maxRetryCount}秒后重试...`;
        this.isLoading = true;
        
        this.retryTimer = setTimeout(() => {
          this.loadingText = `正在重试 (${this.retryCount}/${this.maxRetryCount})...`;
          this.startPlayback();
        }, this.retryDelay);
      } else {
        // 达到最大重试次数，显示错误
        let errorMsg = '播放失败，请检查网络或视频地址';
        if (isString(error)) {
          errorMsg = error;
        } else if (error && error.message) {
          errorMsg = error.message;
        }
        this.handleError(errorMsg);
      }
    },
    
    /**
     * 显示错误信息
     */
    handleError(message) {
      this.isLoading = false;
      this.errorMessage = message;
      this.showError = true;
      this.$emit('error', new Error(message));
    },
    
    /**
     * 组件方法：开始播放
     */
    play() {
      try {
        const videoContext = uni.createVideoContext(this.videoId, this);
        videoContext.play();
        
        // 同步播放音频
        if (this.useSeparateAudio && this.audioContext && typeof this.audioContext.play === 'function') {
          try {
            // 确保音频源已设置
            if (!this.audioContext.src || this.audioContext.src !== this.playUrl) {
              this.setAudioSource(this.playUrl);
            }
            this.audioContext.play();
          } catch (e) {
            console.warn('播放独立音频失败:', e);
          }
        }
        
        this.isPlaying = true;
        this.$emit('play');
      } catch (error) {
        console.error('播放失败:', error);
        this.$emit('error', error);
      }
    },
    
    /**
     * 组件方法：暂停播放
     */
    pause() {
      try {
        const videoContext = uni.createVideoContext(this.videoId, this);
        videoContext.pause();
        
        // 同步暂停音频
        if (this.useSeparateAudio && this.audioContext && typeof this.audioContext.pause === 'function') {
          try {
            this.audioContext.pause();
          } catch (e) {
            console.warn('暂停独立音频失败:', e);
          }
        }
        
        this.isPlaying = false;
        this.$emit('pause');
      } catch (error) {
        console.error('暂停失败:', error);
        this.$emit('error', error);
      }
    },
    
    /**
     * 组件方法：重新加载视频
     */
    reload() {
      this.reloadVideo();
    },
    
    /**
     * 清理资源
     */
    cleanupResources() {
      // 清除定时器
      if (this.retryTimer) {
        clearTimeout(this.retryTimer);
      }
      
      // 清理独立音频上下文（如果有）
      if (this.audioContext) {
        try {
          if (typeof this.audioContext.stop === 'function') {
            this.audioContext.stop();
          }
          if (typeof this.audioContext.destroy === 'function') {
            this.audioContext.destroy();
          }
          this.audioContext = null;
          console.log('音频上下文已清理');
        } catch (error) {
          console.error('清理音频上下文失败:', error);
        }
      }
      
      // 停止播放
      try {
        const videoContext = uni.createVideoContext(this.videoId, this);
        videoContext.pause();
      } catch (error) {
        console.error('停止播放失败:', error);
      }
      
      // iOS平台清理音频会话
      if (this.isIOS) {
        try {
          const AVAudioSession = plus.ios.import('AVAudioSession');
          const session = AVAudioSession.sharedInstance();
          session.setActive(false);
          plus.ios.deleteObject(session);
        } catch (error) {
          console.error('iOS音频会话清理失败:', error);
        }
      }
      
      // 触发销毁事件
      this.$emit('destroy');
      
      // 重置音频检测状态
      this.hasAudioTrack = false;
      this.isAudioDetected = false;
    },
    
    /**
     * 重新加载视频
     */
    reloadVideo() {
      this.retryCount = 0;
      this.isLoading = true;
      this.loadingText = '正在重新加载...';
      this.showError = false;
      this.errorMessage = '';
      
      // 触发重新加载事件
      this.$emit('reload');
      
      // 重置音频检测状态
      this.hasAudioTrack = false;
      this.isAudioDetected = false;
      
      this.$nextTick(() => {
        this.initPlayer();
      });
    },
  }
};
</script>

<style lang="scss" scoped>
.native-rtsp-player {
  width: 100%;
  min-height: 300rpx;
  background-color: #000000;
  display: flex;
  flex-direction: column;
  position: relative;
}

.header {
  height: 88rpx;
  background-color: #1E1E1E;
  display: flex;
  align-items: center;
  padding: 0 30rpx;
  position: relative;
  z-index: 10;
}

.back-button {
  width: 80rpx;
  height: 80rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.title {
  flex: 1;
  color: #FFFFFF;
  font-size: 36rpx;
  font-weight: 500;
  text-align: center;
  padding-right: 80rpx; // 为返回按钮留出空间
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.video-container {
  flex: 1;
  position: relative;
  background-color: #000000;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.video-player {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.h5-notice {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #FFFFFF;
  padding: 60rpx;
}

.notice-text {
  margin-top: 30rpx;
  font-size: 36rpx;
  font-weight: 500;
}

.notice-subtext {
  margin-top: 20rpx;
  font-size: 28rpx;
  color: #CCCCCC;
}

.controls-container {
  padding: 30rpx;
  background-color: #1E1E1E;
  border-top: 1rpx solid #333333;
}

.control-buttons {
  display: flex;
  justify-content: space-around;
  margin-bottom: 30rpx;
}

.control-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20rpx;
}

.btn-text {
  margin-top: 10rpx;
  font-size: 24rpx;
  color: #498CEC;
}

.progress-container {
  display: flex;
  align-items: center;
  margin-top: 20rpx;
}

.time-text {
  color: #CCCCCC;
  font-size: 24rpx;
  width: 80rpx;
  text-align: center;
}

.slider {
  flex: 1;
  margin: 0 20rpx;
}

/* 适配不同平台 */
/* #ifdef MP-WEIXIN */
.video-player {
  object-fit: cover;
}
/* #endif */

/* #ifdef APP-PLUS */
.video-container {
  background-color: #000000;
}

.video-player {
  background-color: #000000;
}
/* #endif */
</style>