summaryrefslogtreecommitdiff
path: root/obsolete/macros/latex/contrib/yt4pdf/yt4pdf.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'obsolete/macros/latex/contrib/yt4pdf/yt4pdf.dtx')
-rw-r--r--obsolete/macros/latex/contrib/yt4pdf/yt4pdf.dtx629
1 files changed, 629 insertions, 0 deletions
diff --git a/obsolete/macros/latex/contrib/yt4pdf/yt4pdf.dtx b/obsolete/macros/latex/contrib/yt4pdf/yt4pdf.dtx
new file mode 100644
index 0000000000..4ca3bcc0b6
--- /dev/null
+++ b/obsolete/macros/latex/contrib/yt4pdf/yt4pdf.dtx
@@ -0,0 +1,629 @@
+%\iffalse
+%<*copyright>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% yt4pdf.sty package, %%
+%% Copyright (C) 2010--2016 D. P. Story %%
+%% dpstory@uakron.edu %%
+%% %%
+%% This program can redistributed and/or modified under %%
+%% the terms of the LaTeX Project Public License %%
+%% Distributed from CTAN archives in directory %%
+%% macros/latex/base/lppl.txt; either version 1 of the %%
+%% License, or (at your option) any later version. %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%</copyright>
+%<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01]
+%<package>\ProvidesPackage{yt4pdf}
+%<package> [2016/10/04 v1.1 yt4pdf: Play You Tube videos in PDF, Acrobat Distiller only (dps)]
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[colorlinks,hyperindex]{hyperref}
+%\pdfstringdefDisableCommands{\let\\\textbackslash}
+%\EnableCrossrefs \CodelineIndex
+\begin{document}
+\def\CMD#1{\textbackslash#1}
+ \GetFileInfo{yt4pdf.sty}
+ \title{\textsf{yt4pdf}: Package for playing You Tube Videos}
+ \author{D. P. Story\\
+ Email: \texttt{dpstory@uakron.edu}}
+ \date{processed \today}
+ \maketitle
+ \tableofcontents
+ \let\Email\texttt
+ \DocInput{yt4pdf.dtx}
+ \PrintIndex
+\end{document}
+%</driver>
+% \fi
+% \MakeShortVerb{|}
+% \StopEventually{}
+%
+% \DoNotIndex{\def,\edef,\gdef,\xdef,\global,\long,\let}
+% \DoNotIndex{\expandafter,\string,\the,\ifx,\else,\fi}
+% \DoNotIndex{\csname,\endcsname,\relax,\begingroup,\endgroup}
+% \DoNotIndex{\DeclareTextCommand,\DeclareTextCompositeCommand}
+% \DoNotIndex{\space,\@empty,\special}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \begin{macrocode}
+\RequirePackage{xkeyval}
+% \end{macrocode}
+% \begin{macrocode}
+\ProcessOptions
+\RequirePackage{rmannot}
+\RequirePackage{popupmenu}[2010/09/18]
+% \end{macrocode}
+%
+% \section{Introduction}
+%
+% I believe that I was vaguely aware of the \href{http://code.google.com/apis/youtube/flash_api_reference.html}
+%{YouTube ActionScript 3.0 Player}, but never pursued it because of my
+%general lack of interest in You Tube (\url{www.youtube.com}). Recently, I
+%became aware of a very nice demo PDF that used the API, see
+%\href{http://www.uvsar.com/pdftube/}{PDF Tube - YouTube API wrapper for PDF
+%documents}. The SWF file and JavaScript are made freely available, so I
+%downloaded it, and was sufficiently impressed to port the example to
+%{\LaTeX} using various members of the {Acro\negthinspace\TeX} Fine Family of Software
+%\verb!:-{)!. The SWF file and JavaScript are due to the good folks at
+%UVSAR (\url{www.uvsar.com}). The UVSAR's sample demo also appeared in the forums of
+%the \href{http://acrobatusers.com/forums/aucbb/viewtopic.php?pid=62134}{Acrobat User
+%Community}.
+%
+% \section{Implementation}
+%
+% \DescribeMacro{\ytFolder} The path to the folder containing
+% the \texttt{pdf\_Tube\_basic.swf} file. This path is set through
+% the \texttt{yt4pdf.cfg} file.
+% \begin{macrocode}
+\newcommand{\ytFolder}{C:/Users/Public/Documents/My TeX Files/%
+tex/latex/aeb/aebpro/yt4pdf/swf}
+% \end{macrocode}
+% \DescribeMacro{ytSWF} The path to \texttt{pdf\_Tube\_basic.swf}, used
+% as an argument for the \cs{rmAnnot} macro.
+% \begin{macrocode}
+\saveNamedPath{ytSWF}{\ytFolder/pdf_tube_basic.swf}
+% \end{macrocode}
+% We input the file \texttt{yt4pdf.cfg} which should contain a re-definition
+% of \cs{ytFolder}, the path to the user's installation containing the
+% \texttt{pdf\_tube\_basic.swf}.
+% \begin{macrocode}
+\InputIfFileExists{yt4pdf.cfg}{}{}
+% \end{macrocode}
+% \subsection{The YouTube RMA}
+% In this section, we define \cs{ytRmAnnot}, a rich media annotation, that is used
+% to play YouTube videos.
+% \begin{macrocode}
+% \end{macrocode}
+% An internal command for getting the rma object based on the current page and the
+% name of the annot.
+% \begin{macrocode}
+\def\yt@namegdef#1{\expandafter\gdef\csname #1\endcsname}
+\def\yt@namexdef#1{\expandafter\xdef\csname #1\endcsname}
+\def\thisNamedRMA(#1){this.getAnnotRichMedia(this.pageNum,"#1")}
+% \end{macrocode}
+% \DescribeMacro{play} This is a key-value pair for the \cs{ytRmAnnot} command.
+% The value of \texttt{play} is a YouTube video ID. When the page the annot is
+% on, the video will be played.
+% \begin{macrocode}
+\define@key{ytRmAnnot}{play}[]{\def\ytrmannot@play{#1}}
+\define@key{ytRmAnnot}{load}[]{\def\ytrmannot@load{#1}}
+\setkeys{ytRmAnnot}{play,load}
+\let\ytCurrRMAName\@empty
+% \end{macrocode}
+% \begin{macro}{\ytRmAnnot}
+% The \cs{ytRmAnnot} creates a rich media annotation using the \textsf{rmannot} package.
+% It uses the SWF file \texttt{pdf\_Tube\_basic.swf} referenced here by the name of
+% \texttt{ytSWF}. The command takes four parametrs:
+% \begin{itemize}
+% \item[\texttt{[\#1]}]: The optional first parameter takes the key-value pairs of the
+% \cs{rmAnnot} command, plus the \texttt{play} key, defined above. The play key is used
+% to set the annot up so it plays automatically when the page is opened.
+% \item[\texttt{\#2}]: The name of this annot, unique to the document. This should be
+% a ``JavaScript variable.'' The name populates the command \cs{ytCurrRMAName}, which is
+% needed for the other commands in this package.
+% \item[\texttt{\#3}]: The width of the annot
+% \item[\texttt{\#4}]: The height of the annot
+% \end{itemize}
+% \begin{macrocode}
+\newcommand{\ytRmAnnot}[4][]{\begingroup
+ \@ifundefined{#2@ytrmname}{\yt@namegdef{#2@ytrmname}{#1}}%
+ {\PackageError{yt2pdf}{The name `#2' is already defined
+ for\MessageBreak this \string\ytRmAnnot}{Choose a unique
+ name for this \string\ytRmAnnot, one different from `#2'.}}%
+ \setkeys*{ytRmAnnot}{#1}\gdef\ytCurrRMAName{#2}%
+ \ifx\ytrmannot@play\@empty\else
+ \makebox[0pt][l]{\pushButton[\BC{}\BG{}\S{S}
+ \AA{\AAPageOpen{aebStartPlayer(\thisNamedRMA(#2),%
+ "\ytrmannot@play",true);}\AAPageClose{aebCancelWait(false);}}
+ ]{btnRmAnnot#2}{1bp}{1bp}}\let\ytrmannot@load\@empty\fi
+ \ifx\ytrmannot@load\@empty
+ \else\makebox[0pt][l]{\pushButton[\BC{}\BG{}\S{S}
+ \AA{\AAPageOpen{aebStartPlayer(\thisNamedRMA(#2),%
+ "\ytrmannot@load",false);}\AAPageClose{aebCancelWait(false);}}
+ ]{btnRmAnnot#2}{1bp}{1bp}}\fi
+ \rmAnnot[\XKV@rm,name=#2,enabled=onclick]{#3}{#4}{ytSWF}%
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+% \DescribeMacro{\DeclareYTName} Defines the internal macro
+% \cs{ytCurrRMAName}. This command is needed in the case were links, or
+% control buttons come before the RMA annot. The first parameter is the
+% page on which the target annot resides, the default is the current page.
+% The second argument is the name of the target annot.
+% code passed is
+% \begin{macrocode}
+\newcommand{\DeclareYTName}[2][]{\def\argi{#1}%
+ \ifx\argi\@empty\gdef\ytCurrRMAName{#2}\else
+ \gdef\ytCurrRMAName{[#1]#2}\fi
+}
+% \end{macrocode}
+% \subsection{Button Controls}
+% We present six control buttons for the rm annot
+% \begin{macro}{\ytBtnPresets}
+% The default appearances of the control buttons.
+% \begin{macrocode}
+\newcommand{\ytBtnPresets}[1]{\def\yt@Presets{#1}}
+\ytBtnPresets{\BC{.5 0 0}\S{S}\textFont{HeBo}\autoCenter{n}}
+% \end{macrocode}
+% \end{macro}
+% The following six commands all take three parameters, the first one optional
+%\begin{enumerate}
+% \item[\texttt{\#1}:] Standard key-value pairs for modifying the
+% appearance of an eforms form field.
+% \item[\texttt{\#2}:]
+% \texttt{this.getAnnotRichMedia(this.pageNum+1, "YouTube")}.
+% \item[\texttt{\#3}:] the width of the button
+% \item[\texttt{\#4}:] the height of the button
+%\end{enumerate}
+% \begin{macro}{\ytPlayToggle}
+% This button has several functions: Pause/Play/Buffering.
+% Initially the button label is on Pause (pressing it pauses a playing video);
+% the button label reads Play when the video is loaded and paused (pressing it plays or resumes
+% the video); while the video is loading, the button label is Buffering...
+% \begin{macro}{\ytStopLoading} Pressing this button stops the streaming of the currently playing
+% video. If the video is started again, there will be some buffering before the play begins.
+% \begin{macro}{\ytMuteToggle} This button toggles and sound off and on. Button labels are
+% MUTE and UNMUTE.
+% \begin{macro}{\ytRewind} If the video is playing, this button
+% stops the video, rewinds it to the beginning, and starts play again. If the video
+% is paused, this button rewinds the video to the beginning, the video remains paused.
+% \begin{macro}{\ytSelect} When this button is pressed, a response dialog opens.
+% The user enters a YouTube video ID into the field. On pressing OK, this video is played.
+% \item[] \textbf{Note:} Some YouTube videos are security
+% restricted and cannot be played through an embedded player, such as the one used here.
+% If video ID of a video that does not allow embedded playback, a dialog appears giving
+% the use to view the video on the web.
+% \begin{macro}{\ytOpenWeb} The user has the option of pressing this button to view the
+% currently video on the web at \texttt{www.youtube.com}.
+% \begin{macrocode}
+% \end{macrocode}
+% The \cs{oyt@RMA} command takes the second parameter of each of the six button commands,
+% and expands it into the appropriate JS code.
+% \begin{macrocode}
+\newcommand{\oyt@RMA}[1][this.pageNum]{\oyt@@RMA[#1]}
+\def\oyt@@RMA[#1]#2\@nil{\gdef\yt@CurrRMAName{#2}%
+ \def\yt@rm{this.getAnnotRichMedia(#1,"#2")}}
+% \end{macrocode}
+% We finally define the six control buttons.
+% \begin{macrocode}
+\newcommand{\ytPlayToggle}[3][]{%
+ \expandafter\oyt@RMA\ytCurrRMAName\@nil%
+ \pushButton[\CA{\ytStrPAUSE}\presets{\yt@Presets}#1
+ \A{\JS{ytPlayToggle(\yt@rm);}}]{playToggle}{#2}{#3}%
+}
+\newcommand{\ytStopLoading}[3][]{%
+ \expandafter\oyt@RMA\ytCurrRMAName\@nil%
+ \pushButton[\CA{\ytStrStopLoading}\presets{\yt@Presets}#1
+ \A{\JS{\yt@rm.callAS("stopVideo");}}]{vidStop}{#2}{#3}%
+}
+\newcommand{\ytMuteToggle}[3][]{%
+ \expandafter\oyt@RMA\ytCurrRMAName\@nil%
+ \pushButton[\CA{\ytStrMUTE}\presets{\yt@Presets}#1
+ \A{\JS{ytMuteToggle(\yt@rm);}}]{muteToggle}{#2}{#3}%
+}
+\newcommand{\ytRewind}[3][]{%
+ \expandafter\oyt@RMA\ytCurrRMAName\@nil%
+ \pushButton[\CA{\ytStrREWIND}\presets{\yt@Presets}#1
+ \A{\JS{ytRewind(\yt@rm);}}]{ytRewind}{#2}{#3}%
+}
+\newcommand{\ytSelect}[4][]{%
+ \expandafter\oyt@RMA\ytCurrRMAName\@nil%
+ \pushButton[\CA{\ytStrLoadVideo}\presets{\yt@Presets}#1
+ \A{\JS{ytSelect(\yt@rm,"#2");}}]{selectVid}{#3}{#4}%
+}
+\newcommand{\ytOpenWeb}[3][]{%
+ \expandafter\oyt@RMA\ytCurrRMAName\@nil%
+ \pushButton[\CA{\ytStrWatchOnWeb}\presets{\yt@Presets}#1
+ \A{\JS{ytOpenWeb(\yt@rm);}}]{playOnWeb}{#2}{#3}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \subsection{Defining a Video Id}
+% \subsubsection{Using a Link}
+% \begin{macro}{\ytvIdPresets}
+% The options for the \cs{ytvId} link. The default is given below in the definition.
+% \begin{macro}{\ytvId}
+% The \cs{ytvId} is link which when pressed plays the video whose Video Id is passed as
+% its second argument.
+% \begin{itemize}
+% \item[\texttt{[\#1]}:] The name of the annot this video is to play in. When
+% this parameter is not specified, the default
+% is \cs{ytCurrRMAName}, which is defined by the \cs{ytRmAnnot} macro.
+% \item[\texttt{\#2}:] The video Id for the YouTube video to play
+% \item[\texttt{\#3}:] The text that displays the link.
+%\end{itemize}
+% \begin{macrocode}
+\newcommand{\ytvIdPresets}[1]{\def\yt@vIdPresets{#1}}
+\ytvIdPresets{\linktxtcolor{webbrown}}
+\newcommand{\ytvId}{\@ifstar{\def\yt@lnk@play{false}\yt@@vId}
+ {\def\yt@lnk@play{true}\yt@@vId}}
+\newcommand{\yt@@vId}[3][\ytCurrRMAName]{%
+ \oyt@RMA#1\@nil\setLink[\presets{\yt@vIdPresets}
+ \A{\JS{aebStartPlayer(\yt@rm,"#2",\yt@lnk@play);}}]{#3}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \subsubsection{Using a Combobox}
+% \begin{macro}{\ytComboList}
+% The \cs{ytComboList} is a combox box of video Ids and titles. The user selects a
+% video based on its title, then presses the PLAY button. The two commands
+% \cs{ytComboListPresets} and \cs{ytComboBtnPresets} are used to set the appearances
+% of the combo box and the PLAY button.
+%\begin{itemize}
+% \item[\texttt{[\#1]}:] eforms key-value pairs
+% \item[\texttt{\#2}:] The width of the combo box
+% \item[\texttt{\#3}:] The height of the combo box
+%\end{itemize}
+% \begin{macro}{\ytComboBtn}
+% A button to play the selection made in the combo box.
+% \begin{macro}{\ytPlayList}
+% This command is executed before \cs{ytComboBtn} to set the play list,
+% and the default value.
+% \begin{macrocode}
+\newcommand{\ytComboListPresets}[1]{\def\yt@ComboListPresets{#1}}
+\newcommand{\ytComboBtnPresets}[1]{\def\yt@ComboBtnPresets{#1}}
+\let\yt@ComboListPresets\@empty
+\let\yt@ComboBtnPresets\@empty
+% \end{macrocode}
+% Use the \cs{ytPlayList} to pass the play list to the next combo box
+% \begin{macrocode}
+\newcommand{\ytPlayList}{\begingroup\@makeother\_\@makeother\'
+ \ytPlayList@i}
+\def\ytPlayList@i#1#2{\gdef\yt@pl@def{#1}\xdef\yt@pl@pl{#2}\endgroup}
+% \end{macrocode}
+% \begin{macro}{\declarePlayList}
+% A video ID may contain characters {\LaTeX} considers special, so we sanitize these
+% special characters before reading in the video ID. Near as I can determine, a video
+% id consists of 11 characters comprising combinations of letters (A-Z,a-z) numbers
+% (0-9) and special characters underscore and hyphen (\_ and -). We sanitize the last two.
+%\begin{verbatim}
+%\declarePlayList{<\cmd>}{
+% \ytIdTitle{<text>}{<VidID>}
+% ...
+% \ytIdTitle{<text>}{<VidID>}
+% }
+%\end{verbatim}
+%The entries may also be in raw form `|[(<VidID>)(<text>)]|'. Note that the two arguments are
+%enclosed in parentheses, there is a problem with parsing if \texttt{<text>} itself contains
+%parentheses. Within \texttt{<text>} enclose matching parentheses in braces, for example,
+%\begin{flushleft}|\ytIdTitle{Kung-Fu Fighting {(Bruce Lee version)}}{GZ9e3Dy7obA}|\end{flushleft}
+% \changes{v1.1}{2016/10/04}{Added \string\cs{declarePlayList}}
+% \begin{macrocode}
+\newcommand{\declarePlayList}{\bgroup
+ \@makeother\_\@makeother\-
+ \yt@declarePlayList}
+\def\yt@declarePlayList#1#2{%
+ \gdef#1{#2}\egroup}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ytIdTitle}
+% A convenience command to lay out the playlist, for example,
+%\begin{verbatim}
+%\declarePlayList{\playListii}{%
+% \ytIdTitle{Elfego Baca}{gRwa0MdeqVs}
+% \ytIdTitle{Texas John Slaughter}{7yrk1BvtLE8}
+% \ytIdTitle{Swamp Fox}{-SBPnw5riLM&NR}
+% \ytIdTitle{Zorro Promo}{cKludhxEoJ0}
+%}
+%\end{verbatim}
+% \begin{macrocode}
+\newcommand{\ytIdTitle}[2]{[(#2)(#1)]}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ytNewBaseName}
+% \cs{ytNewBaseName} is a not so perfect attempt to fix the problem of having
+% multiple combo boxes on one page. The field names need to be distinct. We
+% can pass the new field name using this command.
+% \begin{macro}{\ytResetBaseName}
+% This command resets the field name back to its default value.
+% Both of these commands apply to \cs{ytComboList} and to \cs{ytComboBtn}.
+% \changes{v1.0}{2011/08/23}{Added \cs{ytBaseName} to pass a field title to
+% combo box and controlling play button}
+% \begin{macrocode}
+\newcount\ytListCnt \ytListCnt=0
+\newcommand{\ytNewBaseName}[1][]{%
+ \def\yt@argi{#1}\ifx\yt@argi\@empty\global\advance\ytListCnt1\relax
+ \gdef\yt@BaseName{\yt@CurrRMAName\the\ytListCnt}\else
+ \gdef\yt@BaseName{\yt@CurrRMAName#1}\fi
+}
+\newcommand{\ytResetBaseName}{\gdef\yt@BaseName{\yt@CurrRMAName}}
+\ytResetBaseName
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% Now we have the code for \cs{ytComboList}
+% \begin{macrocode}
+\newcommand{\ytComboList}[3][]{%
+ \expandafter\oyt@RMA\ytCurrRMAName\@nil%
+ \comboBox[\DV{\yt@pl@def}\V{\yt@pl@def}
+ \presets{\yt@ComboListPresets}#1]{ytSelect\yt@BaseName}
+ {#2}{#3}{\yt@pl@pl}%
+}
+% \end{macrocode}
+% The parameters for \cs{ytComboBtn} are
+%\begin{itemize}
+% \item[\texttt{[\#1]}:] The the name of the \cs{ytRmAnnot} this selection is to play in
+% the default is \cs{ytCurrRMAName}.
+% \item[\texttt{\#2}:] The width of the combo box
+% \item[\texttt{\#3}:] The height of the combo box
+% the array of values and titles.
+%\end{itemize}
+% \begin{macrocode}
+\newcommand{\ytComboBtn}[3][]{%
+ \expandafter\oyt@RMA\ytCurrRMAName\@nil%
+ \pushButton[\CA{\ytStrPLAY}\presets{\yt@ComboBtnPresets}#1
+ \A{\JS{var f=this.getField("ytSelect\yt@BaseName");\r
+ aebStartPlayer(\yt@rm,f.value,!event.shift);
+ }}]{ytSelectBtn\yt@BaseName}{#2}{#3}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \subsection{Support for the \textsf{popupmenu} package}
+% \begin{macro}{\ytPopupMenuData}
+% A command use to list the popupmenu data. It defines a command
+% \cs{ytPopupData} that is used in the JS support for popup menus.
+% \begin{macrocode}
+\newcommand{\ytPopupMenuData}[1]{{\toks0={// yt4pdf: Begin popup menu data^^J}%
+ \@tfor\yt@menu:=#1\do{%
+ \toks2=\expandafter{\yt@menu}%
+ \edef\@tmp@exp{\the\toks0\the\toks2^^J}%
+ \toks0=\expandafter{\@tmp@exp}%
+ }\xdef\ytPopupData{\the\toks0// End of popup menu data}%
+}}
+\def\ytPopupData{// No popup menu data defined}%
+% \begin{macro}{\puIdTitle}
+% A convenience macro for entering popupmenu data for youtube videos.
+%\begin{verbatim}
+%\puIdTitle{\string\"Sea Hunt\string\" TV serie}{MW-IZ67iADU}
+%\end{verbatim}
+% Note that we must protect the double quote.
+% \begin{macrocode}
+\newcommand{\puIdTitle}[2]{\item{title={#1},return={[\itemindex,'#2']}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Strings that can be localized}
+% The following strings are used on the buttons, and in the document level JS
+% \begin{macrocode}
+\newcommand{\ytStrPLAY}{PLAY}
+\newcommand{\ytStrREPLAY}{REPLAY}
+\newcommand{\ytStrPAUSE}{PAUSE}
+\newcommand{\ytStrBuffering}{Buffering...}
+\newcommand{\ytStrStopLoading}{Stop Loading}
+\newcommand{\ytStrMUTE}{MUTE}
+\newcommand{\ytStrUNMUTE}{UNMUTE}
+\newcommand{\ytStrREWIND}{REWIND}
+\newcommand{\ytStrLoadVideo}{Load Video}
+\newcommand{\ytStrWatchOnWeb}{Watch on YouTube}
+% response dialog box associated with ytSelect()
+\newcommand{\ytRespQues}{Enter the YouTube Video ID}
+\newcommand{\ytRespTitle}{Load a Video}
+\newcommand{\ytRespLabel}{ID:}
+% alert error messages
+\newcommand{\ytStrErrorVideoNotFound}{Error: Video not found}
+\newcommand{\ytStrErrorNoEmbed}{Error: This video does not allow
+ embedded playback \r\r Would you like to view this video
+ on the web?}
+\newcommand{\ytStrConnecTimedOut}{Connection timed out, try again.}
+% \end{macrocode}
+%
+% \subsection{Document level JavaScript}
+% \begin{macrocode}
+\begin{insDLJS*}[ytPlayToggle]{yt}
+\begin{newsegment}{yt4PDF: YouTube for PDF JavaScript}
+/*
+ Document-level script for YouTube player
+ Document-level script for the PDFtube embedded YouTube player
+ ***************************************************************
+ Functions to be called by buttons or links on the PDF
+ in each case, "rm" is the RichMedia annot containing the player
+ All these are optional and can be renamed or edited as required
+ ***********************************************************
+*/
+// toggle play/pause (button labels updated by event functions)
+function ytPlayToggle(rm) {
+ var ps = rm.callAS("getPlayerState");
+ rm.callAS((ps == 1)? "pauseVideo" : "playVideo");
+}
+// toggle mute (have to update button labels ourselves)
+function ytMuteToggle(rm) {
+ var im = rm.callAS("isMuted");
+ if (im) {
+ event.target.buttonSetCaption("\ytStrMUTE");
+ rm.callAS("unMute");
+ } else {
+ event.target.buttonSetCaption("\ytStrUNMUTE");
+ rm.callAS("mute");
+ }
+}
+// Ask the user for the ID number of a new video, and play it
+function ytSelect(rm,vID) {
+ var rsp = app.response({
+ cQuestion: "\ytRespQues",
+ cTitle: "\ytRespTitle",
+ cDefault: vID,
+ cLabel: "\ytRespLabel"});
+ if (rsp !=null && rsp != "")
+ aebStartPlayer(rm,rsp,true); // dps
+}
+// open the video's YouTube page in the web browser
+function ytOpenWeb(rm) {
+ var link = rm.callAS("getVideoUrl");
+ if (link != null) {
+ app.launchURL(link,true);
+ rm.activated = false;
+ }
+}
+// rewind (seek to zero)
+function ytRewind(rm) { rm.callAS("seekTo",0); }
+/*
+ ************************************************************
+ Functions called by the player itself, in response to events
+ as the events are "external", the annot is not the target.
+ These functions must exist and match the names in the SWF.
+ ***********************************************************
+*/
+function ytPlayerReady() {
+
+ // this is the place to load your default video - for example...
+ console.println("<YT> Player loaded and ready");
+ // this.getAnnotsRichMedia(this.pageNum)[0].callAS("loadVideoById",
+ // "eNzrn8-JFSE",0);
+ aebStartPlayer.isPlayerReady=true; // dps
+}
+function ytStateChange(st) {
+ // Possible values are unstarted (-1), ended (0), playing (1),
+ // paused (2), buffering (3), video cued (5)
+ var lbl = "";
+ console.println("<YT> State changed to " + st);
+ if (st == 0) lbl = "\ytStrREPLAY";
+ else if (st == 1) lbl = "\ytStrPAUSE";
+ else if (st == 3) lbl = "\ytStrBuffering";
+ else if (st == 2 || st == 5) lbl = "\ytStrPLAY";
+ if (lbl) this.getField("playToggle").buttonSetCaption(lbl);
+}
+function ytPlaybackQualityChange(str) {
+ // Possible values are "small", "medium", "large" and "hd720"
+ console.println("<YT> Quality changed to " + str);
+}
+function ytProgress(q) {
+ // q has four properties that you can use to update form fields,
+ // such as...
+ //this.getField("currentTime").value = q.CurrentTime;
+ //this.getField("Duration").value = q.Duration;
+ //this.getField("BytesLoaded").value = q.BytesLoaded;
+ //this.getField("BytesTotal").value = q.BytesTotal;
+}
+function ytError(err) {
+ // Video cannot be played
+ console.println("<YT> ERROR code " + err + " received");
+ if (err == 100)
+ app.alert("\ytStrErrorVideoNotFound", 0, 0, "YouTube");
+ else {
+ var resp=app.alert("\ytStrErrorNoEmbed", 1, 3, "YouTube");
+ if (resp==4) {
+ aebCancelWait(false);
+ ytOpenWeb(aebStartPlayer.annot);
+ }
+ }
+}
+/*
+ We start the player if the annot is activated, if not,
+ we set annot.activated=true, and wait for the widget to say it
+ is ready. When ready, ytPlayerReady() sets
+ aebStartPlayer.isPlayerReady=true
+*/
+function aebStartPlayer(rm,Id,bPlay) {
+ aebStartPlayer.annot=rm;
+ if (aebStartPlayer.annot.activated)
+ aebStartPlayer.annot.callAS(%
+(bPlay)?"loadVideoById":"cueVideoById",Id,0);
+ else {
+ aebCancelWait(false);
+ aebStartPlayer.annot.activated=true;
+ aebStartPlayer.isPlayerReady=false;
+ aebStartPlayer.twait=app.setInterval(%
+'aebWait4Ready(\"'+Id+'\",'+bPlay+');',250);
+ aebStartPlayer.to=app.setTimeOut("aebCancelWait(true)", 10000);
+ }
+}
+aebStartPlayer.isPlayerReady=false;
+aebStartPlayer.twait=null;
+aebStartPlayer.to=null;
+/*
+ If the player is ready, we start the video, and clear
+ the setInterval, otherwise, we wait.
+*/
+function aebWait4Ready(Id,bPlay) {
+ if (aebStartPlayer.isPlayerReady) {
+ aebCancelWait(false);
+ aebStartPlayer.annot.callAS(%
+(bPlay)?"loadVideoById":"cueVideoById",Id,0);
+ }
+}
+function aebCancelWait(bNotify) {
+ var twait=aebStartPlayer.twait;
+ if (aebStartPlayer.to!=null)
+ try { app.clearTimeOut(aebStartPlayer.to); } catch(e) {};
+ aebStartPlayer.to=null;
+ if (aebStartPlayer.twait!=null)
+ try { app.clearInterval(aebStartPlayer.twait); } catch(e) {}
+ aebStartPlayer.twait=null;
+ if ( bNotify && twait!=null ) app.alert("\ytStrConnecTimedOut");
+}
+\end{newsegment}
+\begin{newsegment}{Popup Menu Data and JS}
+\ytPopupData
+var aChoice;
+function ytProcessMenu(aMenu) {
+ var cChoice = \popUpMenu(aMenu);
+ if ( cChoice != null ) {
+ aChoice=eval(cChoice);
+ if (aChoice[1]=="") return null;
+ var thisChoice=aChoice[0];
+ if (ytProcessMenu.nChoice==undefined) {
+ ytProcessMenu.nChoice=thisChoice;
+ eval("aMenu"+ytProcessMenu.nChoice).bMarked=true;
+ } else {
+ eval("aMenu"+ytProcessMenu.nChoice).bMarked=false;
+ var oldnChoice=ytProcessMenu.nChoice;
+ ytProcessMenu.nChoice=thisChoice;
+ eval("aMenu"+ytProcessMenu.nChoice).bMarked=(oldnChoice==ytProcessMenu.nChoice)?false:true;
+ }
+ return aChoice;
+ } else return null;
+}
+function ytPopupMenu(rmaName,ytmenu) {
+ var aChoice=ytProcessMenu(ytmenu);
+ var rm=this.getAnnotRichMedia(this.pageNum,rmaName);
+ if (aChoice!=null) {
+ if (ytProcessMenu.lastDescrip==undefined) {
+ aebStartPlayer(rm,aChoice[1],!event.shift);
+ } else {
+ if (ytProcessMenu.lastDescrip!=aChoice[1]) {
+ aebStartPlayer(rm,aChoice[1],!event.shift);
+ }
+ }
+ ytProcessMenu.lastDescrip=aChoice[1];
+ }
+}
+\end{newsegment}
+\end{insDLJS*}
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+\endinput
+
+rm=this.getAnnotRichMedia(this.pageNum,"YouTube1");
+rm.callAS("cueVideoById", "GZ9e3Dy7obA");