Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't Add video or audio to premade presentation #1740

Open
patolax opened this issue Jun 24, 2024 · 2 comments
Open

Can't Add video or audio to premade presentation #1740

patolax opened this issue Jun 24, 2024 · 2 comments
Assignees

Comments

@patolax
Copy link

patolax commented Jun 24, 2024

Describe the bug
Can't Add video or audio to premade presentations

To Reproduce
This is my code, I load a PowerPoint presentation from disk and make text changes to the slide after I call these methods to add audio/video.

public void AddVideoToPresentation(PresentationDocument presentationDocument, string audioFilePath)
{
    int PicID = 915;
    PresentationPart presentationPart = presentationDocument.PresentationPart;
    var slideCount = presentationPart.Presentation.SlideIdList.Count();
    var videoEmbedId = string.Format("audioId{0}{1}", slideCount, PicID++);
    var mediaEmbedId = string.Format("medId{0}{1}", slideCount, PicID++);

    SlidePart slidepart = presentationDocument.PresentationPart.SlideParts.LastOrDefault();

    MediaDataPart mediaDataPart1 = presentationDocument.CreateMediaDataPart("audio/mp3", ".mp3");
    System.IO.Stream mediaDataPart1Stream = File.OpenRead(audioFilePath);
    mediaDataPart1.FeedData(mediaDataPart1Stream);
    mediaDataPart1Stream.Close();

    slidepart.AddAudioReferenceRelationship(mediaDataPart1, videoEmbedId);
    slidepart.AddMediaReferenceRelationship(mediaDataPart1, mediaEmbedId);

    slidepart.Slide.Save();

    AddVid(presentationDocument);
}


public void AddVid(PresentationDocument presentationDocument)
{
    PresentationPart presentationPart = presentationDocument.PresentationPart;
    SlidePart slidepart = presentationDocument.PresentationPart.AddNewPart<SlidePart>("rxId3");
    MediaDataPart mediaDataPart1 = presentationDocument.CreateMediaDataPart("video/mp4", ".mp4");
    System.IO.Stream mediaDataPart1Stream = System.IO.File.Open(@"D:\samplevideo.mp4", System.IO.FileMode.Open);
    mediaDataPart1.FeedData(mediaDataPart1Stream);
    mediaDataPart1Stream.Close();

    slidepart.AddMediaReferenceRelationship(mediaDataPart1, "rxId2");
    slidepart.AddVideoReferenceRelationship(mediaDataPart1, "rxId1");
}

Observed behavior
No Video or audio embedded in the presentation

Expected behavior
Play audio after slide transition

Desktop (please complete the following information):

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net6.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
    <PackageReference Include="Microsoft.Office.Interop.PowerPoint" Version="15.0.4420.1018" />
    <PackageReference Include="Mscc.GenerativeAI" Version="1.5.0" />
    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
    <PackageReference Include="OpenXmlPowerTools.NetCore" Version="1.1.0" />
    <PackageReference Include="System.ServiceModel.Syndication" Version="8.0.0" />
  </ItemGroup>

  <ItemGroup>
    <Reference Include="office">
      <HintPath>..\..\..\..\..\Windows\assembly\GAC_MSIL\office\15.0.0.0__71e9bce111e9429c\OFFICE.DLL</HintPath>
    </Reference>
  </ItemGroup>

</Project>
@yswenli
Copy link

yswenli commented Jul 15, 2024

How to add video or audio to a pre made presentation?

@mkaszewiak
Copy link
Collaborator

mkaszewiak commented Jan 31, 2025

Hi @yswenli
Please see the sample code that adds video and audio. Code requires video, audio and picture path to be changed to match files path on your environment.
The code has been produced and tested on the latest Open XML SDK 3.2.0
I see you are still using older version 2.2.0 so please update to the 3.2.0 if possible before testing the sample.
Please let me know how it works for you. Thanks

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Presentation;
using A = DocumentFormat.OpenXml.Drawing;
using P14 = DocumentFormat.OpenXml.Office2010.PowerPoint;
using ShapeTree = DocumentFormat.OpenXml.Presentation.ShapeTree;
using ShapeProperties = DocumentFormat.OpenXml.Presentation.ShapeProperties;
using NonVisualDrawingProperties = DocumentFormat.OpenXml.Presentation.NonVisualDrawingProperties;
using NonVisualPictureProperties = DocumentFormat.OpenXml.Presentation.NonVisualPictureProperties;
using NonVisualPictureDrawingProperties = DocumentFormat.OpenXml.Presentation.NonVisualPictureDrawingProperties;
using Picture = DocumentFormat.OpenXml.Presentation.Picture;
using BlipFill = DocumentFormat.OpenXml.Presentation.BlipFill;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Office2016.Drawing;


string imgEmbedId = "rId4", embedId = "rId3", mediaEmbedId = "rId2";
string filePath = @"C:\source\TestFiles\MyPresentation.pptx";
string videoFilePath = @"C:\source\TestFiles\video.mp4";
string coverPicPath = @"C:\source\TestFiles\sample.png";
string audioFilePath = @"C:\source\TestFiles\audio.mp3";

using (PresentationDocument presentationDocument = PresentationDocument.Open(filePath, true))
{

    if (presentationDocument.PresentationPart == null || presentationDocument.PresentationPart.Presentation.SlideIdList == null)
    {
        throw new NullReferenceException("Presenation Part is empty or there are no slides");
    }

    //Get presentation part
    PresentationPart presentationPart = presentationDocument.PresentationPart;

    //Get slides ids.
    OpenXmlElementList slidesIds = presentationPart.Presentation.SlideIdList.ChildElements;

    int lastSlideIndex = presentationPart.Presentation.SlideIdList.Count() - 1;

    //gets relationsipIds of the 2 last slides
    string? videoSlidePartRelationshipId = ((SlideId)slidesIds[lastSlideIndex - 1]).RelationshipId;
    string? audioSlidePartRelationshipId = ((SlideId)slidesIds[lastSlideIndex]).RelationshipId;


    if (videoSlidePartRelationshipId == null || audioSlidePartRelationshipId == null)
    {
        throw new NullReferenceException("Slides ids not found");

    }

    //Get slide part by relationshipID
    SlidePart? videoSlidepart = (SlidePart)presentationPart.GetPartById(videoSlidePartRelationshipId);
    SlidePart? audioSlidepart = (SlidePart)presentationPart.GetPartById(audioSlidePartRelationshipId);

    //Adds vide 
    AddVideo(videoSlidepart, presentationDocument);

    //Adds audio 
    AddAudio(audioSlidepart, presentationDocument);

}


void AddVideo(SlidePart slidePart, PresentationDocument presentationDocument)
{
    // Create video Media Data Part (content type, extension)
    MediaDataPart mediaDataPart = presentationDocument.CreateMediaDataPart("video/mp4", ".mp4");

    //Get the video file and feed the stream
    using (Stream mediaDataPartStream = File.OpenRead(videoFilePath))
    {
        mediaDataPart.FeedData(mediaDataPartStream);
    }
    //Adds a VideoReferenceRelationship to the MainDocumentPart
    slidePart.AddVideoReferenceRelationship(mediaDataPart, embedId);

    //Adds a MediaReferenceRelationship to the SlideLayoutPart
    slidePart.AddMediaReferenceRelationship(mediaDataPart, mediaEmbedId);

    NonVisualDrawingProperties nonVisualDrawingProperties = new NonVisualDrawingProperties() { Id = (UInt32Value)4U, Name = "video" };
    A.VideoFromFile videoFromFile = new A.VideoFromFile() { Link = embedId };

    ApplicationNonVisualDrawingProperties appNonVisualDrawingProperties = new ApplicationNonVisualDrawingProperties();
    appNonVisualDrawingProperties.Append(videoFromFile);

    //Adds all the elements to the slide part
    AddMediaToTheSlide(slidePart, nonVisualDrawingProperties, appNonVisualDrawingProperties);

}

void AddAudio(SlidePart slidePart, PresentationDocument presentationDocument)
{
    // Create video Media Data Part (content type, extension)
    MediaDataPart mediaDataPart = presentationDocument.CreateMediaDataPart("audio/mp3", ".mp3");

    //Feeds the stream with audio file
    using (Stream mediaDataPartStream = File.OpenRead(audioFilePath))
    {
        mediaDataPart.FeedData(mediaDataPartStream);
    }

    slidePart.AddAudioReferenceRelationship(mediaDataPart, embedId);
    slidePart.AddMediaReferenceRelationship(mediaDataPart, mediaEmbedId);

    NonVisualDrawingProperties nonVisualDrawingProperties = new NonVisualDrawingProperties() { Id = (UInt32Value)4U, Name = "audio" };

    A.AudioFromFile audioFromFile = new A.AudioFromFile() { Link = embedId };
    ApplicationNonVisualDrawingProperties appNonVisualDrawingProperties = new ApplicationNonVisualDrawingProperties();
    appNonVisualDrawingProperties.Append(audioFromFile);

    AddMediaToTheSlide(slidePart, nonVisualDrawingProperties, appNonVisualDrawingProperties);

}
void AddMediaToTheSlide(SlidePart slidePart, NonVisualDrawingProperties nonVisualDrawingProperties, ApplicationNonVisualDrawingProperties applicationNonVisualDrawingProperties)

{
    //adds sample image to the slide with id to be used as reference in blip
    ImagePart imagePart = slidePart.AddImagePart(ImagePartType.Png, imgEmbedId);
    using (Stream data = File.OpenRead(coverPicPath))
    {
        imagePart.FeedData(data);
    }

    if (slidePart!.Slide!.CommonSlideData!.ShapeTree == null)
    {
        throw new NullReferenceException("Presenation shape tree is empty");
    }

    //Getting existing shape tree object from PowerPoint
    ShapeTree shapeTree = slidePart.Slide.CommonSlideData.ShapeTree;

    // specifies the existence of a picture within a presentation.
    // It can have non-visual properties, a picture fill as well as shape properties attached to it.
    Picture picture = new Picture();
    NonVisualPictureProperties nonVisualPictureProperties = new NonVisualPictureProperties();

    //When the hyperlink text is clicked the Action is fetched
    A.HyperlinkOnClick hyperlinkOnClick = new A.HyperlinkOnClick() { Id = "", Action = "ppaction://media" };
    nonVisualDrawingProperties.Append(hyperlinkOnClick);

    NonVisualPictureDrawingProperties nonVisualPictureDrawingProperties = new NonVisualPictureDrawingProperties();
    A.PictureLocks pictureLocks = new A.PictureLocks() { NoChangeAspect = true };
    nonVisualPictureDrawingProperties.Append(pictureLocks);

    ApplicationNonVisualDrawingPropertiesExtensionList appNonVisualDrawingPropertiesExtensionList = new 
    ApplicationNonVisualDrawingPropertiesExtensionList();
    ApplicationNonVisualDrawingPropertiesExtension appNonVisualDrawingPropertiesExtension = new 
    ApplicationNonVisualDrawingPropertiesExtension() { Uri = "{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}" };

    P14.Media media = new() { Embed = mediaEmbedId };
    media.AddNamespaceDeclaration("p14", "http://schemas.microsoft.com/office/powerpoint/2010/main");
    appNonVisualDrawingPropertiesExtension.Append(media);
    appNonVisualDrawingPropertiesExtensionList.Append(appNonVisualDrawingPropertiesExtension);

    applicationNonVisualDrawingProperties.Append(appNonVisualDrawingPropertiesExtensionList);

    nonVisualPictureProperties.Append(nonVisualDrawingProperties);
    nonVisualPictureProperties.Append(nonVisualPictureDrawingProperties);
    nonVisualPictureProperties.Append(applicationNonVisualDrawingProperties);

    //Prepare shape properties to display picture
    BlipFill blipFill = new BlipFill();
    A.Blip blip = new A.Blip() { Embed = imgEmbedId };

    A.Stretch stretch = new A.Stretch();
    A.FillRectangle fillRectangle = new A.FillRectangle();
    A.Transform2D transform2D = new A.Transform2D();
    A.Offset offset = new A.Offset() { X = 1524000L, Y = 857250L };
    A.Extents extents = new A.Extents() { Cx = 9144000L, Cy = 5143500L };
    A.PresetGeometry presetGeometry = new A.PresetGeometry() { Preset = A.ShapeTypeValues.Rectangle };
    A.AdjustValueList adjValueList = new A.AdjustValueList();

    stretch.Append(fillRectangle);
    blipFill.Append(blip);
    blipFill.Append(stretch);
    transform2D.Append(offset);
    transform2D.Append(extents);
    presetGeometry.Append(adjValueList);

    ShapeProperties shapeProperties = new ShapeProperties();

    shapeProperties.Append(transform2D);
    shapeProperties.Append(presetGeometry);

    //adds all elements to the slide's shape tree
    picture.Append(nonVisualPictureProperties);
    picture.Append(blipFill);
    picture.Append(shapeProperties);

    shapeTree.Append(picture);

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants