---
title: "Multimedia Annotations"
canonical_url: "https://www.nutrient.io/guides/android/samples/multimedia-annotations-kotlin/"
md_url: "https://www.nutrient.io/guides/android/samples/multimedia-annotations-kotlin.md"
last_updated: "2026-05-15T19:10:04.916Z"
description: "Add video and gallery link annotations to a document at runtime."
---

# Multimedia Annotations

Add video and gallery link annotations to a document at runtime.

[Get Started](https://www.nutrient.io/sdk/android/getting-started.md)

[All Samples](https://www.nutrient.io/guides/android/samples.md)

[Download](https://www.nutrient.io/guides/android/downloads.md)

[Launch Demo](https://www.nutrient.io/demo/)

---

```kotlin

/*
 *   Copyright © 2018-2026 PSPDFKit GmbH. All rights reserved.
 *
 *   The PSPDFKit Sample applications are licensed with a modified BSD license.
 *   Please see License for details. This notice may not be removed from this file.
 */
package com.pspdfkit.catalog.examples.kotlin

import android.content.Context
import android.graphics.RectF
import android.net.Uri
import androidx.activity.viewModels
import com.pspdfkit.annotations.LinkAnnotation
import com.pspdfkit.annotations.actions.UriAction
import com.pspdfkit.catalog.R
import com.pspdfkit.catalog.SdkExample
import com.pspdfkit.catalog.tasks.ExtractAssetTask
import com.pspdfkit.configuration.activity.PdfActivityConfiguration
import com.pspdfkit.document.PdfDocument
import com.pspdfkit.ui.PdfActivity
import com.pspdfkit.ui.PdfActivityIntentBuilder
import org.intellij.lang.annotations.Language
import java.io.File
import kotlin.getValue

/** This example showcases how to dynamically add multimedia content to a PDF document.  */
class DynamicMultimediaAnnotationExample(context: Context) :
    SdkExample(context, R.string.dynamicMultimediaExampleTitle, R.string.dynamicMultimediaExampleDescription) {
    override fun launchExample(context: Context, configuration: PdfActivityConfiguration.Builder) {
        // Before launching the example, we extract one video file to the private app folder. This
        // file will be used to dynamically add
        // another link annotation to the document at runtime.
        ExtractAssetTask.extract("media/videos/small.mp4", title, context, false, "mp4") { videoFile: File? ->
            // Next extract the demo document and launch it.
            ExtractAssetTask.extract(WELCOME_DOC, title, context) { documentFile: File? ->
                // For normal multimedia content playback, it is not necessary to subclass PdfActivity as no custom code is required (only
                // annotations using the pspdfkit:// scheme have to be present). However, if you want to dynamically add multimedia annotations
                // to a document, it is preferable to do this using a custom activity class (as done by this example).
                val intent =
                    PdfActivityIntentBuilder.fromUri(context, Uri.fromFile(documentFile)).configuration(configuration.build()).activityClass(MultimediaAnnotationsActivity::class.java).build()

                // Pass the file system path to our video file to the activity. The activity will use the path to dynamically add a multimedia link
                // annotation to the PDF for opening the extracted video.
                intent.putExtra(MultimediaAnnotationsActivity.EXTRA_VIDEO_PATH, videoFile!!.getAbsolutePath())
                context.startActivity(intent)
            }
        }
    }
}

/**
 * This activity is part of the [DynamicMultimediaAnnotationExample] and shows how to dynamically add multimedia annotations to a PDF document.
 */
class MultimediaAnnotationsActivity : PdfActivity() {
    private val viewModel: AnnotationCreationViewModel by viewModels()

    companion object {
        /** This is the filesystem path of a video file we're going to dynamically add to the PDF document. */
        const val EXTRA_VIDEO_PATH = "videoPath"
    }

    override fun onDocumentLoaded(document: PdfDocument) {
        super.onDocumentLoaded(document)

        viewModel.createObjects {
            // We add a video link to the first page.
            addVideoAnnotation()

            // We add a gallery link to the second page.
            addGalleryAnnotation()
        }
    }

    /**
     * This method adds a link annotation to a video on the local file system.
     */
    private fun addVideoAnnotation() {
        // Get the rect for the link annotation we want to add. We're using absolute page coordinates here, but your app can use different positioning techniques
        // like for example using multimedia position data that you would retrieve from your server. This rect is in the center of the page, so tapping the
        // page will trigger the video.
        val linkAnnotationRect = RectF(0f, 768f, 768f, 256f)

        // We're going to place the video on the first page of the document.
        val pageIndex = 0

        // The activity was launched with the path to a video on the local file system. We're going to use this file for playback with the multimedia annotation.
        val videoPathUri =
            intent.getStringExtra(EXTRA_VIDEO_PATH)?.let { Uri.fromFile(File(it)) }?: throw IllegalStateException("No string value found for $EXTRA_VIDEO_PATH.")

        // Create the link annotation. The LinkAnnotation constructor takes the index of the page on which the annotation will be added.
        val multimediaLinkAnnotation =
            LinkAnnotation(pageIndex).apply {
                // Set the position of the link annotation on the page.
                boundingBox = linkAnnotationRect

                // To let the link point to the multimedia content, we have to set a UriAction on the link. The UriAction encodes the actual URL of the content.
                // The multimedia URL uses the pspdfkit:// URL scheme, has optional options in square brackets, followed by the local file system URI of the file.
                // Note the the videoPathUri also carries a file:// scheme which is required for video discovery. For a comprehensive list of supported URI formats
                // and options, please consult our Multimedia Annotation online guides at: https://nutrient.io/guides/android/annotations/multimedia-annotations/
                action = UriAction("pspdfkit://[autoplay:true]$videoPathUri")
            }

        // Add the annotation to the document and show it.
        requirePdfFragment().addAnnotationToPage(multimediaLinkAnnotation, false)

        // The line above uses the fragment to add the annotation to the document. This will immediately update the rendered page too, making the newly added
        // annotation visible. Alternatively, you can use the document's annotation provider, and manually trigger an annotation updated notification on the
        // fragment. Like so:
        //
        //   document.annotationProvider.addAnnotationToPage(multimediaLinkAnnotation)
        //   fragment.notifyAnnotationHasChanged(multimediaLinkAnnotation)
    }

    /**
     * This method adds a link annotation to a custom gallery on the local file system.
     */
    private fun addGalleryAnnotation() {
        // This example defines a custom JSON content for the gallery. It writes this JSON to a local file and then create an annotation pointing to the file.
        // See our online guides at https://nutrient.io/guides/android/annotations/multimedia-annotations/ for a full specification of the JSON format
        // used by galleries.
        @Language("JSON")
        val galleryJson =
            """
            [
              {
                "contentURL": "https://farm4.staticflickr.com/3701/13630138733_abf2411bd1_z.jpg",
                "caption": "This is a local image. Captions are optional"
              },
              {
                "contentURL": "https://farm3.staticflickr.com/2157/3527157206_f3ebec9909_z.jpg",
                "caption": "This is a local image. Captions are optional"
              }
            ]
            """.trimIndent()

        // Write the JSON to a local gallery file on the file system. It is important that the file uses the.gallery file extension so that Nutrient can
        // recognize the file for showing a gallery.
        val outputFile =
            filesDir.resolve("sample.gallery").apply {
                // For the sake of this example, we recreate the gallery file from scratch. We therefore delete it if it already exists.
                if (exists()) delete()
                // Write the whole JSON to the output file.
                writeText(galleryJson)
            }

        // Get the rect for the link annotation we want to add. We're using absolute page coordinates here. These are the same coordinates used by the video
        // annotation created in the method above, but we're adding the gallery to the second page (instead of the first one).
        val linkAnnotationRect = RectF(0f, 768f, 768f, 256f)

        // We're going to place the gallery on the second page of the document.
        val pageIndex = 1

        // Pointing the link to the gallery file is enough for showing the gallery. It is essential that Uri.fromFile() is used, so that the path inside the
        // link annotation has the correct format and includes the file:// URL scheme.
        val galleryPathUri = Uri.fromFile(outputFile)

        // Create the link annotation. The LinkAnnotation constructor takes the index of the page on which the annotation will be added.
        val galleryLinkAnnotation =
            LinkAnnotation(pageIndex).apply {
                // Set the position of the link annotation on the page.
                boundingBox = linkAnnotationRect

                // To let the link point to the gallery file, we have to set a UriAction on the link. The UriAction encodes the actual URL of the content.
                // The multimedia URL uses the pspdfkit:// URL scheme followed by the local file system URI of the file. Galleries don't support multimedia options.
                // Note the the galleryPathUri also carries a file:// scheme which is required for gallery discovery. For a comprehensive list of supported URI
                // formats, please consult our Multimedia Annotation online guides at: https://nutrient.io/guides/android/annotations/multimedia-annotations/
                action = UriAction("pspdfkit://$galleryPathUri")
            }

        // Add the annotation to the document and show it.
        pdfFragment?.addAnnotationToPage(galleryLinkAnnotation, false)
    }
}

```

This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.

---

## Related pages

- [Application Policy](/guides/android/samples/application-policy-kotlin.md)
- [Custom Form Highlight Color](/guides/android/samples/custom-form-highlight-color-java.md)
- [Custom Page Templates](/guides/android/samples/custom-page-templates-java.md)
- [Digital Signature (Basic)](/guides/android/samples/digital-signature-basic-kotlin.md)
- [Disabled Annotation Property](/guides/android/samples/disabled-annotation-property-java.md)
- [Image Document](/guides/android/samples/image-document-kotlin.md)
- [Compose Image Document](/guides/android/samples/compose-image-document-kotlin.md)
- [Inline Multimedia](/guides/android/samples/inline-multimedia-kotlin.md)
- [JavaScript Form Filling](/guides/android/samples/javascript-form-filling-kotlin.md)
- [Overlay Visibility](/guides/android/samples/overlay-visibility-kotlin.md)
- [PdfFragment](/guides/android/samples/pdffragment-kotlin.md)
- [Reader View](/guides/android/samples/reader-view-kotlin.md)
- [Playground](/guides/android/samples/playground-kotlin.md)
- [JavaScript Calculator](/guides/android/samples/javascript-calculator-kotlin.md)
- [Text Field Suggestions](/guides/android/samples/text-field-suggestions-kotlin.md)
- [Thumbnail Bar Modes](/guides/android/samples/thumbnail-bar-modes-kotlin.md)
- [Signature Storage Database](/guides/android/samples/signature-storage-database-kotlin.md)
- [Selection Customization](/guides/android/samples/selection-customization-java.md)
- [Password Protected PDF](/guides/android/samples/password-protected-pdf-kotlin.md)
- [Scientific Paper](/guides/android/samples/scientific-paper-kotlin.md)
- [Try Instant](/guides/android/samples/try-instant-kotlin.md)
- [Merge Documents](/guides/android/samples/merge-documents-kotlin.md)
- [Annotation Rendering](/guides/android/samples/annotation-rendering-kotlin.md)
- [Custom Data Provider](/guides/android/samples/custom-data-provider-kotlin.md)
- [Annotations with Transparency](/guides/android/samples/annotations-with-transparency-kotlin.md)
- [Annotation Flags](/guides/android/samples/annotation-flags-kotlin.md)
- [AI Assistant (Multiple Documents, ViewPager)](/guides/android/samples/ai-assistant-multiple-documents-viewpager-kotlin.md)
- [Custom Sharing Menu](/guides/android/samples/custom-sharing-menu-java.md)
- [Add LTV to Existing Signature](/guides/android/samples/add-ltv-to-existing-signature-kotlin.md)
- [Custom Toolbar Grouping](/guides/android/samples/custom-toolbar-grouping-java.md)
- [Custom Layout](/guides/android/samples/custom-layout-kotlin.md)
- [Custom ActionBar Actions](/guides/android/samples/custom-actionbar-actions-kotlin.md)
- [Custom Activity Toolbars](/guides/android/samples/custom-activity-toolbars-java.md)
- [Custom Note Hinter](/guides/android/samples/custom-note-hinter-kotlin.md)
- [Custom Main Toolbar](/guides/android/samples/custom-main-toolbar-kotlin.md)
- [Annotation Configuration](/guides/android/samples/annotation-configuration-kotlin.md)
- [Annotation Selection Styling](/guides/android/samples/annotation-selection-styling-kotlin.md)
- [Custom Search UI (Compose)](/guides/android/samples/custom-search-ui-compose-kotlin.md)
- [Document Switcher](/guides/android/samples/document-switcher-java.md)
- [File Annotation Creation](/guides/android/samples/file-annotation-creation-kotlin.md)
- [Dynamic Pages on Scroll](/guides/android/samples/dynamic-pages-on-scroll-kotlin.md)
- [Custom Activity Form Editing](/guides/android/samples/custom-activity-form-editing-java.md)
- [Custom Stamp Annotations](/guides/android/samples/custom-stamp-annotations-java.md)
- [Custom Outline Provider](/guides/android/samples/custom-outline-provider-kotlin.md)
- [Compose Navigation](/guides/android/samples/compose-navigation-kotlin.md)
- [Fragment Runtime Configuration](/guides/android/samples/fragment-runtime-configuration-kotlin.md)
- [Annotation Overlay](/guides/android/samples/annotation-overlay-java.md)
- [Instant Document JSON](/guides/android/samples/instant-document-json-kotlin.md)
- [DocumentView Composable](/guides/android/samples/documentview-composable-kotlin.md)
- [Form Creation](/guides/android/samples/form-creation-kotlin.md)
- [Document Download](/guides/android/samples/document-download-kotlin.md)
- [JavaScript Actions](/guides/android/samples/javascript-actions-kotlin.md)
- [Instant JSON Attachment](/guides/android/samples/instant-json-attachment-kotlin.md)
- [Digital Signature (Manual)](/guides/android/samples/digital-signature-manual-kotlin.md)
- [Digital Signature (Third-Party)](/guides/android/samples/digital-signature-third-party-kotlin.md)
- [Inline Search](/guides/android/samples/inline-search-java.md)
- [Form Filling](/guides/android/samples/form-filling-kotlin.md)
- [Form Click Intercept (Compose)](/guides/android/samples/form-click-intercept-compose-kotlin.md)
- [Document Sharing](/guides/android/samples/document-sharing-java.md)
- [Custom Download Dialog](/guides/android/samples/custom-download-dialog-java.md)
- [Download Progress](/guides/android/samples/download-progress-kotlin.md)
- [Popup Toolbar Customization](/guides/android/samples/popup-toolbar-customization-kotlin.md)
- [Custom Sharing Dialog](/guides/android/samples/custom-sharing-dialog-java.md)
- [PDF from Image](/guides/android/samples/pdf-from-image-kotlin.md)
- [Digital Signature (Two-Step)](/guides/android/samples/digital-signature-two-step-kotlin.md)
- [Remote URL](/guides/android/samples/remote-url-kotlin.md)
- [PdfUiFragment](/guides/android/samples/pdfuifragment-kotlin.md)
- [Runtime Configuration](/guides/android/samples/runtime-configuration-kotlin.md)
- [Sound Extraction](/guides/android/samples/sound-extraction-kotlin.md)
- [Document from Canvas](/guides/android/samples/document-from-canvas-kotlin.md)
- [Tabbed Documents](/guides/android/samples/tabbed-documents-kotlin.md)
- [Watermarks](/guides/android/samples/watermarks-kotlin.md)
- [Programmatic Zoom](/guides/android/samples/programmatic-zoom-kotlin.md)
- [Signature Parcelize](/guides/android/samples/signature-parcelize-kotlin.md)
- [OCR](/guides/android/samples/ocr-kotlin.md)
- [Vertical Scrollbar](/guides/android/samples/vertical-scrollbar-java.md)
- [Split View](/guides/android/samples/split-view-java.md)
- [XFDF Import/Export](/guides/android/samples/xfdf-import-export-kotlin.md)
- [UI View Modes](/guides/android/samples/ui-view-modes-kotlin.md)
- [LTV Signature](/guides/android/samples/ltv-signature-kotlin.md)
- [Bookmark Highlighting](/guides/android/samples/bookmark-highlighting-kotlin.md)
- [Custom Annotation Inspector](/guides/android/samples/custom-annotation-inspector-java.md)
- [Annotation Sidebar](/guides/android/samples/annotation-sidebar-kotlin.md)
- [AI Assistant (Single Document)](/guides/android/samples/ai-assistant-single-document-kotlin.md)
- [AI Assistant (Multiple Documents, Compose)](/guides/android/samples/ai-assistant-multiple-documents-compose-kotlin.md)
- [Document Comparison](/guides/android/samples/document-comparison-kotlin.md)
- [Document Processing](/guides/android/samples/document-processing-kotlin.md)
- [Custom Annotation Creation Toolbar](/guides/android/samples/custom-annotation-creation-toolbar-java.md)
- [Custom Electronic Signature](/guides/android/samples/custom-electronic-signature-java.md)
- [E-Learning](/guides/android/samples/e-learning-kotlin.md)
- [Electronic + Digital Signing](/guides/android/samples/electronic-digital-signing-kotlin.md)
- [Generate PDF Report](/guides/android/samples/generate-pdf-report-kotlin.md)
- [Forms with JavaScript](/guides/android/samples/forms-with-javascript-kotlin.md)
- [External Document](/guides/android/samples/external-document-kotlin.md)
- [Overlay Views](/guides/android/samples/overlay-views-kotlin.md)
- [Kiosk Grid](/guides/android/samples/kiosk-grid-kotlin.md)
- [Search Indexing](/guides/android/samples/search-indexing-kotlin.md)
- [Annotation Creation](/guides/android/samples/annotation-creation-kotlin.md)
- [Filterable Thumbnail Grid](/guides/android/samples/filterable-thumbnail-grid-kotlin.md)
- [Tabbed Documents (Persistent)](/guides/android/samples/tabbed-documents-persistent-kotlin.md)
- [Measurement Tools](/guides/android/samples/measurement-tools-kotlin.md)
- [HTML-to-PDF Conversion](/guides/android/samples/html-to-pdf-conversion-kotlin.md)
- [AES Encrypted File](/guides/android/samples/aes-encrypted-file-java.md)
- [Construction Floor Plan](/guides/android/samples/construction-floor-plan-kotlin.md)
- [Hide and Reveal Areas](/guides/android/samples/hide-and-reveal-areas-kotlin.md)
- [Multiple Documents (Compose Pager)](/guides/android/samples/multiple-documents-compose-pager-kotlin.md)
- [Screen Reader](/guides/android/samples/screen-reader-java.md)
- [Custom Search UI (Views)](/guides/android/samples/custom-search-ui-views-java.md)

