SharePoint / sp-dev-docs

SharePoint & Viva Connections Developer Documentation
https://docs.microsoft.com/en-us/sharepoint/dev/
Creative Commons Attribution 4.0 International
1.24k stars 1k forks source link

SPFx Play HTML5 Videos dynamically on a webpart not working #6604

Closed vivekmurli closed 2 years ago

vivekmurli commented 3 years ago

Category

We are developing a webpart

  1. That has a textbox where we supply a Video URL
  2. This would fetch the Video URL from a SharePoint list on button click and set the SRC of the Video Element.

We are developing a webpart

That has a textbox where we supply a Video URL

This would fetch the Video URL from a SharePoint list on button click and set the SRC of the Video Element.

Code

function textFieldChanged(newValue: string){ 

    let vidplay = document.getElementById('VidPlayer');
    let source = document.createElement('source');
    source.setAttribute('src', newValue);
    vidplay.appendChild(source);
    vidplay.load();
    vidplay.play();

    sp.web.currentUser.get().then((user: ISiteUserInfo) => {

      console.log("user", user);
      const userId: number = user.Id;

      sp.web.lists.getByTitle(videoList).
        items.select("ID", "User/ID", "VideoURL")
        .expand("User")
        .filter(`VideoURL eq '${decodeURIComponent(newValue)}' and User/ID eq '${userId}'`)
        .top(1)
        .get()
        .then((videos: IVideoEntry[]) => {
          console.log("Videos", videos);

          // Did we find a video?
          if (videos.length > 0) {
            //Update the record
            const video: IVideoEntry = videos[0];
            console.log("We found the video", video);

          }
        });
    });         
    }

Video Player Element

<div>
      <video
        id="VidPlayer"
        ref={videoRef}
        style={{ width: elementWidth }}
        src={txtParam}
      //controls
      ></video>< br/>

      <TextField id="txtVideoURL" onChange={(ev,newValue)=> {txtParam=newValue}}/> 

      <DefaultButton text="Submit" onClick={()=>{textFieldChanged(txtParam)}}/>

</div>

Read a lot of articles pertaining to the same, however unable to use .play() and .load() which is required to load the video element and then play.

We get an error "Property 'play' does not exist on type 'HTMLElement'.ts(2339)"

image

Would appreciate if anyone could let me know how this can be handled in SPFx and if there is a way to play/toggle videos dynamically

ghost commented 3 years ago

Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.

StfBauer commented 3 years ago

Sadly I can only see partially of your code but when you request:

let vidplay = document.getElementById('VidPlay');
...
vidplay.play();

Will never work because the native HTML implementation has not such a function in the HTML DOM.

Instead you need to cast the element the following way.

let vidplay : HTMLVideoElement = document.getElementById('Vidplay');
...
vidplay.play()

Another more fundamental issue is that you can only host one instance of the video player on the page by using it with an ID.

HTML Element register a global variable on the Window object that then get's overwritten by the second instance of your video play.

So in your case it is most likely you will get only the last instance of getElementById and this is the only video you can play.

vivekmurli commented 3 years ago

@StfBauer Thank you for the reply Stefan

I have tried typecasting in the past and get the below error

image

Is there any other way to play Videos dynamically on the webpart? or a workaround?

I've also read a few posts on stackoverflow where this has been achieved outside SharePoint on JS based projects where once the SRC is set dynamically , we have to call the load and then the play button to play the 2nd video

Any help would be appreciated

StfBauer commented 3 years ago

Sorry had an issue there as it seems, was just coded on top of my head.

I would do something linke this.

  public render(): void {

    this.domElement.innerHTML = `
      <div class="${styles.video}">
        <video class='thisvideoplayer'></video>
      </div>`;

    let videoPlayer = <HTMLCollectionOf<HTMLVideoElement>>
      this.domElement.getElementsByClassName('thisvideoplayer');

    if (videoPlayer.length !== 0) {
      videoPlayer[0].load();
      videoPlayer[0].play();
    }

  }

Or like in your scenario with getElementById, which I would not use:

    let videoPlayer = <HTMLVideoElement>document.getElementById('thisvideoplayer');

    videoPlayer.load();
    videoPlayer.play();
kongmengfei commented 3 years ago

@vivekmurli ,

I noticed that your project is React web part, please take a referenece of below demo:

Test:

test Baker Kong Microsoft SharePoint Community Support

vivekmurli commented 3 years ago

@kongmengfei I see that you have used a hardcoded URL , does it work when you change the URL on the textbox?

vivekmurli commented 3 years ago

@StfBauer thank you for helping me out with this.. unfortunately the issue still persists... Is there a way we can collaborate on this? Any help would be appreciated

VesaJuvonen commented 2 years ago

This issue is closed as there has not have been any activity on it within the past 2 months. If the issue is still valid, please submit a new issue with updated details. Sorry for the Inconvenience. We are perform this cleaning operation for all inactive issues in this repository to be able to improve our support model in future.

ghost commented 2 years ago

Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: Issue List: Our approach to locked issues