首页 新闻 会员 周边

我用angular2做了一个播放功能,但是有用户反应听了一段就断了

0
悬赏园豆:5 [已解决问题] 解决于 2018-07-07 17:07

最近用angular2开发了一个播放器的小页面,但有小部分人反映听了一段就停了,是什么原因,也没有捕获到时什么错误

问题补充:
import { Injectable, EventEmitter } from '@angular/core';
import { Audio } from '../model/audio';
import { PlayData } from '../model/play-data';
import { OriginalAudio } from '../model/original-audio';
/**
 * 音频服务,只关心播放列表控制与进度控制
 * 不提供组件支持,只提供列表控制方法接口及进度控制接口
 */
@Injectable()
export class AudioService {
  public playDataEvent: EventEmitter<PlayData>;
  public playEndEvent: EventEmitter<Audio>;
  // 主音频标签
  private _audio: HTMLAudioElement;
  // 当前列表中的音频
  private playList: Audio[];
  // 当前播放的数据
  private playData: PlayData;
  private listenInterval;
  // 播放模式 1循环 2:单 3:随机
  private playModel: number;
  // 当前播放的详细数据
  private currAudioData: Audio;
  /**
   * 创建新的音频标签
   */
  constructor() {

    this.playDataEvent = new EventEmitter();
    this.playEndEvent = new EventEmitter();

     this._audio = document.createElement('audio');



    this._audio.autoplay = false;
    this.playModel = 1;
    this._audio.onplay = () => {
      let that = this;
      this.listenInterval = window.setInterval(() => {
        that.playData.Current = that._audio.currentTime;
        that.playData.Url = that._audio.src;
        that.playData.During = that._audio.duration;
        that.playData.Data = that._audio.buffered &&
          that._audio.buffered.length ?
          (that._audio.buffered.end(0) || 0) :
          0;
      }, 1000);
      this.playData.IsPlaying = true;
      this.currAudioData = this.playList[this.playData.Index];
      this.playDataEvent.next(this.playData);
    };
    this._audio.onended = () => {
      window.clearInterval(this.listenInterval);
      this.FillPlayData();
      this.playData.IsPlaying = false;
      this.playData.Current = 0;
      this.playDataEvent.next(this.playData);
      this.playEndEvent.next(this.playList[this.playData.Index]);
      this.TryNext();
    };
    this._audio.onabort = () => {
      window.clearInterval(this.listenInterval);
      this.playData.Current = this._audio.currentTime;
      this.playData.Url = this._audio.src;
      this.playData.During = this._audio.duration;
      this.playData.Data = this._audio.buffered &&
        this._audio.buffered.length ?
        (this._audio.buffered.end(0) || 0) :
        0;
      this.playData.IsPlaying = false;
    };
    this._audio.onpause = () => {
      window.clearInterval(this.listenInterval);
      this.playData.Current = this._audio.currentTime;
      this.playData.Url = this._audio.src;
      this.playData.During = this._audio.duration;
      this.playData.Data = this._audio.buffered &&
        this._audio.buffered.length ?
        (this._audio.buffered.end(0) || 0) :
        0;
      this.playData.IsPlaying = false;
      this.playDataEvent.next(this.playData);
    };
    this.playData = { Style: 0, Index: 0 };
    this.playList = [];
  }

  /**
   * 1.列表中无此音频则添加并播放
   * 2.列表中存在此音频但未播放则播放
   * 3.列表中存在此音频且在播放则暂停
   * @param audio
   */
  public Toggle(audio?: Audio): void {
    let tryGet = audio ?
      this.playList.findIndex((p) => p.Url === audio.Url) :
      this.playData.Index;
    if (tryGet < 0) {
      this.playList.push(audio);
      this.PlayIndex(this.playList.length);
    } else {
      if (tryGet === this.playData.Index) {
        if (this._audio.paused) {
          this._audio.play();
          this.playData.IsPlaying = true;
        } else {
          this._audio.pause();
          this.playData.IsPlaying = false;
        }
      } else {
        this.PlayIndex(tryGet);
      }
    }
  }

  /**
   * 若列表中无此音频则添加到列表的最后
   * 若列表中无音频则添加后并播放
   * @param audio
   */
  public Add(audio: Audio): void {
    this.playList.push(audio);
    if (this.playList.length === 1) {
      this.PlayIndex(0);
    }
  }

  /**
   * 移除列表中指定索引的音频
   * 若移除的就是正在播放的音频则自动播放新的同索引音频,不存在此索引则递减
   * 若只剩这一条音频了则停止播放并移除
   * @param index
   */
  public Remove(index: number): void {
    this.playList.splice(index, 1);
    if (!this.playList.length) {
      this._audio.src = '';
    } else {
      this.PlayIndex(index);
    }
  }

  /**
   * 下一曲
   */
  public Next(): void {
    switch (this.playData.Style) {
      case 0:
        if (this.playData.Index < this.playList.length) {
          this.playData.Index++;
          this.PlayIndex(this.playData.Index);
        }
        break;
      case 1:
        this.playData.Index = (this.playData.Index + 1) % this.playList.length;
        this.PlayIndex(this.playData.Index);
        break;
      case 2:
        this.playData.Index = (this.playData.Index + 1) % this.playList.length;
        this.PlayIndex(this.playData.Index);
        console.log('暂不考虑随机播放将视为列表循环播放');
        break;
      case 3:
        this._audio.currentTime = 0;
        break;
      default:
        if (this.playData.Index < this.playList.length) {
          this.playData.Index++;
          this.PlayIndex(this.playData.Index);
        }
        break;
    }
  }
  /**
   * 上一曲
   */
  public Prev(): void {
    switch (this.playData.Style) {
      case 0:
        if (this.playData.Index > 0) {
          this.playData.Index--;
          this.PlayIndex(this.playData.Index);
        }
        break;
      case 1:
        this.playData.Index = (this.playData.Index - 1) < 0 ?
          (this.playList.length - 1) :
          (this.playData.Index - 1);
        this.PlayIndex(this.playData.Index);
        break;
      case 2:
        this.playData.Index = (this.playData.Index - 1) < 0 ?
          (this.playList.length - 1) :
          (this.playData.Index - 1);
        this.PlayIndex(this.playData.Index);
        console.log('暂不考虑随机播放将视为列表循环播放');
        break;
      case 3:
        this._audio.currentTime = 0;
        break;
      default:
        if (this.playData.Index > 0) {
          this.playData.Index--;
          this.PlayIndex(this.playData.Index);
        }
        break;
    }
  }

  /**
   * 将当前音频跳转到指定百分比进度处
   * @param percent
   */
  public Skip(percent: number): void {
    this._audio.currentTime = this._audio.duration * percent;
    this.playData.Current = this._audio.currentTime;
  }

  public PlayList(): Audio[] {
    return this.playList;
  }

  public PlayData(): PlayData {
    return this.playData;
  }

  /**
   * 用于播放最后强行填满进度条
   * 防止播放进度偏差导致的用户体验
   */
  private FillPlayData(): void {
    this.playData.Current = this._audio.duration;
    this.playData.Data = this._audio.duration;
  }

  /**
   * 尝试播放指定索引的音频
   * 索引不存在则尝试递增播放,又失败则递减播放,又失败则失败
   * @param index
   */
  private PlayIndex(index: number): void {

    index = this.playList[index] ? index :
      this.playList[index + 1] ? (index + 1) :
        this.playList[index - 1] ? (index - 1) : -1;
    if (index !== -1) {
      this._audio.src = this.playList[index].Url;
      if (this._audio.paused) {
        this._audio.play();
        this.playData.IsPlaying = true;
      }
      this.playData.Index = index;
    } else {
      console.log('nothing to be play');
    }
  }
  private TryNext(): void {
    if (this.playModel === 1) {
      if (this.playData.Index > (this.playList.length - 1)) {
        this.PlayIndex(0);
      }
      this.Next();
    } else if (this.playModel === 2) {
      const index = this.playData.Index;
      this.PlayIndex(index);
    } else if (this.playModel === 3) {
      const max = this.playList.length;
      const num = Math.random() * max;
      const index = parseInt(num.toString(), 10);
      this.PlayIndex(index);
    }
  }
  /**
     * 设置播放模式
     */
  public SetPlayModel(model: number): void {
    if (model === 1) {
      this.playModel = 1;
    } else if (model === 2) {
      this.playModel = 2;
    } else if (model === 3) {
      this.playModel = 3;
    }
  }
  public getCurrAudioData(): Audio {
    return this.currAudioData;
  }
  /**
     * 全部播放
     */
  public AddRange(list: Audio[],auto=false): void {
    this.playData.IsPlaying = false;
    this.playList = [];
    list.forEach(x => {
      const tryIndex = this.playList.findIndex((p) => p.Url === x.Url);
      if (tryIndex < 0) {
        this.playList.push(x);
      }
    });
    this.PlayIndex(0);
    if(auto==false) this._audio.pause();
  }
  /**
     * OriginalAudio 类型转 Audio类型
     */
  public ConvertToAudio(x: OriginalAudio): Audio {
    const audio: Audio = {
      Cover: x.Cover,
      DuringSecond: '',
      Id: x.Id,
      Size: 0,
      Title: x.Title,
      Url: x.Source
    };
    return audio;
  }
  /**
     * 预加载
     * 设置  playData playList
     */
  public PreLoad() {
    if (this.playList.length > 0) {
      if (this.playData.Url === undefined) {
        this.PrePlayIndex();
      }
    }
  }
  private PrePlayIndex(): void {
    this._audio.src = this.playList[0].Url;
    if (this._audio.paused) {
      this.playData.IsPlaying = false;
    }
    this.playData.Index = 0;
  }
  public Run(index) {
    this.PlayIndex(index);
  }
}

这个是播放的核心代码

生活还是要继续的主页 生活还是要继续 | 初学一级 | 园豆:10
提问于:2017-12-11 08:44
< >
分享
最佳答案
0

没有代码,不知道播放啥玩意儿,不知道小部分人是干啥的,不知道是什么网络,这是新的综艺节目

《蒙面编程大神猜猜猜》么?

收获园豆:5
爱编程的大叔 | 高人七级 |园豆:30839 | 2017-12-11 09:18
其他回答(2)
0

css3不是可以直接加video标签了吗

不会么么哒 | 园豆:205 (菜鸟二级) | 2017-12-11 11:11

不太理解你想要表达的意思,你说明白点?我的问题是为什以有的播放了一段就停了

支持(0) 反对(0) 生活还是要继续 | 园豆:10 (初学一级) | 2017-12-11 11:14
0

自己解决了

生活还是要继续 | 园豆:10 (初学一级) | 2018-07-07 17:06
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册