first import
This commit is contained in:
4
sites/all/modules/media_archive/CHANGELOG.txt
Normal file
4
sites/all/modules/media_archive/CHANGELOG.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
CHANGELOG for Media: Archive
|
||||
|
||||
by aaron: Add provider file for archive.org videos.
|
274
sites/all/modules/media_archive/LICENSE.txt
Normal file
274
sites/all/modules/media_archive/LICENSE.txt
Normal file
@@ -0,0 +1,274 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute
|
||||
verbatim copies of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to
|
||||
share and change it. By contrast, the GNU General Public License is
|
||||
intended to guarantee your freedom to share and change free software--to
|
||||
make sure the software is free for all its users. This General Public License
|
||||
applies to most of the Free Software Foundation's software and to any other
|
||||
program whose authors commit to using it. (Some other Free Software
|
||||
Foundation software is covered by the GNU Library General Public License
|
||||
instead.) You can apply it to your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the
|
||||
freedom to distribute copies of free software (and charge for this service if
|
||||
you wish), that you receive source code or can get it if you want it, that you
|
||||
can change the software or use pieces of it in new free programs; and that
|
||||
you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to
|
||||
deny you these rights or to ask you to surrender the rights. These restrictions
|
||||
translate to certain responsibilities for you if you distribute copies of the
|
||||
software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for
|
||||
a fee, you must give the recipients all the rights that you have. You must make
|
||||
sure that they, too, receive or can get the source code. And you must show
|
||||
them these terms so they know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and (2)
|
||||
offer you this license which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain that
|
||||
everyone understands that there is no warranty for this free software. If the
|
||||
software is modified by someone else and passed on, we want its recipients
|
||||
to know that what they have is not the original, so that any problems
|
||||
introduced by others will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents. We
|
||||
wish to avoid the danger that redistributors of a free program will individually
|
||||
obtain patent licenses, in effect making the program proprietary. To prevent
|
||||
this, we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
|
||||
MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains a notice
|
||||
placed by the copyright holder saying it may be distributed under the terms
|
||||
of this General Public License. The "Program", below, refers to any such
|
||||
program or work, and a "work based on the Program" means either the
|
||||
Program or any derivative work under copyright law: that is to say, a work
|
||||
containing the Program or a portion of it, either verbatim or with
|
||||
modifications and/or translated into another language. (Hereinafter, translation
|
||||
is included without limitation in the term "modification".) Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not covered
|
||||
by this License; they are outside its scope. The act of running the Program is
|
||||
not restricted, and the output from the Program is covered only if its contents
|
||||
constitute a work based on the Program (independent of having been made
|
||||
by running the Program). Whether that is true depends on what the Program
|
||||
does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's source
|
||||
code as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this License
|
||||
and to the absence of any warranty; and give any other recipients of the
|
||||
Program a copy of this License along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you
|
||||
may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion of it,
|
||||
thus forming a work based on the Program, and copy and distribute such
|
||||
modifications or work under the terms of Section 1 above, provided that you
|
||||
also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in whole or in
|
||||
part contains or is derived from the Program or any part thereof, to be
|
||||
licensed as a whole at no charge to all third parties under the terms of this
|
||||
License.
|
||||
|
||||
c) If the modified program normally reads commands interactively when run,
|
||||
you must cause it, when started running for such interactive use in the most
|
||||
ordinary way, to print or display an announcement including an appropriate
|
||||
copyright notice and a notice that there is no warranty (or else, saying that
|
||||
you provide a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this License.
|
||||
(Exception: if the Program itself is interactive but does not normally print such
|
||||
an announcement, your work based on the Program is not required to print
|
||||
an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Program, and can be
|
||||
reasonably considered independent and separate works in themselves, then
|
||||
this License, and its terms, do not apply to those sections when you distribute
|
||||
them as separate works. But when you distribute the same sections as part
|
||||
of a whole which is a work based on the Program, the distribution of the
|
||||
whole must be on the terms of this License, whose permissions for other
|
||||
licensees extend to the entire whole, and thus to each and every part
|
||||
regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your rights to
|
||||
work written entirely by you; rather, the intent is to exercise the right to
|
||||
control the distribution of derivative or collective works based on the
|
||||
Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of a
|
||||
storage or distribution medium does not bring the other work under the scope
|
||||
of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it, under
|
||||
Section 2) in object code or executable form under the terms of Sections 1
|
||||
and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable source
|
||||
code, which must be distributed under the terms of Sections 1 and 2 above
|
||||
on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three years, to give
|
||||
any third party, for a charge no more than your cost of physically performing
|
||||
source distribution, a complete machine-readable copy of the corresponding
|
||||
source code, to be distributed under the terms of Sections 1 and 2 above on
|
||||
a medium customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer to distribute
|
||||
corresponding source code. (This alternative is allowed only for
|
||||
noncommercial distribution and only if you received the program in object
|
||||
code or executable form with such an offer, in accord with Subsection b
|
||||
above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source code
|
||||
means all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation and
|
||||
installation of the executable. However, as a special exception, the source
|
||||
code distributed need not include anything that is normally distributed (in
|
||||
either source or binary form) with the major components (compiler, kernel,
|
||||
and so on) of the operating system on which the executable runs, unless that
|
||||
component itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering access to
|
||||
copy from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place counts as distribution of the source code,
|
||||
even though third parties are not compelled to copy the source along with the
|
||||
object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program except as
|
||||
expressly provided under this License. Any attempt otherwise to copy,
|
||||
modify, sublicense or distribute the Program is void, and will automatically
|
||||
terminate your rights under this License. However, parties who have received
|
||||
copies, or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not signed it.
|
||||
However, nothing else grants you permission to modify or distribute the
|
||||
Program or its derivative works. These actions are prohibited by law if you
|
||||
do not accept this License. Therefore, by modifying or distributing the
|
||||
Program (or any work based on the Program), you indicate your acceptance
|
||||
of this License to do so, and all its terms and conditions for copying,
|
||||
distributing or modifying the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the original
|
||||
licensor to copy, distribute or modify the Program subject to these terms and
|
||||
conditions. You may not impose any further restrictions on the recipients'
|
||||
exercise of the rights granted herein. You are not responsible for enforcing
|
||||
compliance by third parties to this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues), conditions
|
||||
are imposed on you (whether by court order, agreement or otherwise) that
|
||||
contradict the conditions of this License, they do not excuse you from the
|
||||
conditions of this License. If you cannot distribute so as to satisfy
|
||||
simultaneously your obligations under this License and any other pertinent
|
||||
obligations, then as a consequence you may not distribute the Program at all.
|
||||
For example, if a patent license would not permit royalty-free redistribution
|
||||
of the Program by all those who receive copies directly or indirectly through
|
||||
you, then the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply and
|
||||
the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any patents or
|
||||
other property right claims or to contest validity of any such claims; this
|
||||
section has the sole purpose of protecting the integrity of the free software
|
||||
distribution system, which is implemented by public license practices. Many
|
||||
people have made generous contributions to the wide range of software
|
||||
distributed through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing to
|
||||
distribute software through any other system and a licensee cannot impose
|
||||
that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original copyright
|
||||
holder who places the Program under this License may add an explicit
|
||||
geographical distribution limitation excluding those countries, so that
|
||||
distribution is permitted only in or among countries not thus excluded. In such
|
||||
case, this License incorporates the limitation as if written in the body of this
|
||||
License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will be
|
||||
similar in spirit to the present version, but may differ in detail to address new
|
||||
problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program specifies
|
||||
a version number of this License which applies to it and "any later version",
|
||||
you have the option of following the terms and conditions either of that
|
||||
version or of any later version published by the Free Software Foundation. If
|
||||
the Program does not specify a version number of this License, you may
|
||||
choose any version ever published by the Free Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free programs
|
||||
whose distribution conditions are different, write to the author to ask for
|
||||
permission. For software which is copyrighted by the Free Software
|
||||
Foundation, write to the Free Software Foundation; we sometimes make
|
||||
exceptions for this. Our decision will be guided by the two goals of
|
||||
preserving the free status of all derivatives of our free software and of
|
||||
promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
|
||||
PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
|
||||
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
|
||||
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
|
||||
AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR
|
||||
ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
|
||||
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
|
||||
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
|
||||
ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
|
||||
OR DATA BEING RENDERED INACCURATE OR LOSSES
|
||||
SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
|
||||
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN
|
||||
IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Create a Archive Stream Wrapper class for the Media/Resource module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create an instance like this:
|
||||
* $archive = new ResourceArchiveStreamWrapper('archive://?v=[video-code]');
|
||||
*/
|
||||
class MediaArchiveStreamWrapper extends MediaReadOnlyStreamWrapper {
|
||||
protected $base_url = 'http://archive.org/file';
|
||||
|
||||
function getTarget($f) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static function getMimeType($uri, $mapping = NULL) {
|
||||
return 'video/archive';
|
||||
}
|
||||
|
||||
function getOriginalThumbnailPath() {
|
||||
$parts = $this->get_parameters();
|
||||
return 'http://www.archive.org/download/'. check_plain($parts['v']) .'/' . check_plain($parts['v']) .'.thumbs/' . check_plain($parts['org']) .'_000001.jpg';
|
||||
|
||||
}
|
||||
|
||||
function getLocalThumbnailPath() {
|
||||
$parts = $this->get_parameters();
|
||||
$local_path = 'public://media-archive/' . check_plain($parts['v']) . '.jpg';
|
||||
if (!file_exists($local_path)) {
|
||||
$dirname = drupal_dirname($local_path);
|
||||
file_prepare_directory($dirname, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
|
||||
@copy($this->getOriginalThumbnailPath(), $local_path);
|
||||
}
|
||||
return $local_path;
|
||||
}
|
||||
}
|
5
sites/all/modules/media_archive/README.txt
Normal file
5
sites/all/modules/media_archive/README.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
Media: Archive
|
||||
|
||||
Creates a Archive PHP Stream Wrapper for Resource and implements the various
|
||||
formatter and file listing hooks in the Media module.
|
21
sites/all/modules/media_archive/css/media_archive.css
Normal file
21
sites/all/modules/media_archive/css/media_archive.css
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
.media-archive-preview-wrapper {
|
||||
max-width: 100%;
|
||||
min-height: 50px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.media-archive-preview-wrapper object,
|
||||
.media-archive-preview-wrapper iframe {
|
||||
max-width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.media-archive-preview-wrapper .js-fallback {
|
||||
left: 0;
|
||||
margin-top: -0.5em;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
top: 50%;
|
||||
}
|
BIN
sites/all/modules/media_archive/images/stream-archive.png
Normal file
BIN
sites/all/modules/media_archive/images/stream-archive.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file media_archive/includes/media_archive.styles.inc
|
||||
* Styles definitions for Media: Archive.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of Styles module hook_styles_default_containers().
|
||||
*/
|
||||
function media_archive_styles_default_containers() {
|
||||
// We append Archive to the file containers.
|
||||
return array(
|
||||
'file' => array(
|
||||
'containers' => array(
|
||||
'media_archive' => array(
|
||||
'class' => 'MediaArchiveStyles',
|
||||
'name' => 'media_archive',
|
||||
'label' => t('Archive'),
|
||||
'preview' => 'media_archive_preview_style',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of Styles module hook_styles_default_presets().
|
||||
*/
|
||||
function media_archive_styles_default_presets() {
|
||||
return array(
|
||||
'file' => array(
|
||||
'containers' => array(
|
||||
'media_archive' => array(
|
||||
'default preset' => 'linked_thumbnail',
|
||||
'styles' => array(
|
||||
'original' => array(
|
||||
'default preset' => 'video',
|
||||
),
|
||||
'thumbnail' => array(
|
||||
'default preset' => 'linked_thumbnail',
|
||||
),
|
||||
'square_thumbnail' => array(
|
||||
'default preset' => 'linked_square_thumbnail',
|
||||
),
|
||||
'medium' => array(
|
||||
'default preset' => 'linked_medium',
|
||||
),
|
||||
'large' => array(
|
||||
'default preset' => 'large_video',
|
||||
),
|
||||
),
|
||||
'presets' => array(
|
||||
'unlinked_thumbnail' => array(
|
||||
array(
|
||||
'name' => 'thumbnail',
|
||||
'settings' => array(),
|
||||
),
|
||||
),
|
||||
'linked_thumbnail' => array(
|
||||
array(
|
||||
'name' => 'link_to_media',
|
||||
'settings' => array(),
|
||||
),
|
||||
array(
|
||||
'name' => 'thumbnail',
|
||||
'settings' => array(),
|
||||
),
|
||||
),
|
||||
'linked_square_thumbnail' => array(
|
||||
array(
|
||||
'name' => 'link_to_media',
|
||||
'settings' => array(),
|
||||
),
|
||||
array(
|
||||
'name' => 'image_style',
|
||||
'settings' => array(
|
||||
'image_style' => 'square_thumbnail',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'thumbnail',
|
||||
'settings' => array(),
|
||||
),
|
||||
),
|
||||
'linked_medium' => array(
|
||||
array(
|
||||
'name' => 'link_to_media',
|
||||
'settings' => array(),
|
||||
),
|
||||
array(
|
||||
'name' => 'image_style',
|
||||
'settings' => array(
|
||||
'image_style' => 'medium',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'thumbnail',
|
||||
'settings' => array(),
|
||||
),
|
||||
),
|
||||
'video' => array(
|
||||
array(
|
||||
'name' => 'video',
|
||||
'settings' => array(),
|
||||
),
|
||||
),
|
||||
'large_video' => array(
|
||||
array(
|
||||
'name' => 'resize',
|
||||
'settings' => array(
|
||||
'width' => 480,
|
||||
'height' => 360,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'video',
|
||||
'settings' => array(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class MediaArchiveStyles extends FileStyles {
|
||||
public $autoplay;
|
||||
public $fullscreen;
|
||||
|
||||
function get_autoplay() {
|
||||
return $this->get('autoplay');
|
||||
}
|
||||
function set_autoplay($value) {
|
||||
return $this->set('autoplay', $value);
|
||||
}
|
||||
function get_fullscreen() {
|
||||
return $this->get('fullscreen');
|
||||
}
|
||||
function set_fullscreen($value) {
|
||||
return $this->set('fullscreen', $value);
|
||||
}
|
||||
|
||||
function get_image_uri() {
|
||||
if ($image_uri = $this->get('image_uri')) {
|
||||
return $image_uri;
|
||||
}
|
||||
$object = $this->get_object();
|
||||
if ($object->uri) {
|
||||
$wrapper = file_stream_wrapper_get_instance_by_uri($object->uri);
|
||||
return $wrapper->getLocalThumbnailPath();
|
||||
}
|
||||
}
|
||||
function video($effect) {
|
||||
$variables = array(
|
||||
'uri' => $this->get_uri(),
|
||||
'width' => $this->get_width(),
|
||||
'height' => $this->get_height(),
|
||||
'autoplay' => $this->get_autoplay(),
|
||||
'fullscreen' => $this->get_fullscreen(),
|
||||
);
|
||||
$this->set_output(theme('media_archive_video', $variables));
|
||||
}
|
||||
}
|
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file media_archive/includes/media_archive.variables.inc
|
||||
* Variable defaults for Media: Archive.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define our constants.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the variable namespace, automatically prepended to module variables.
|
||||
*/
|
||||
define('MEDIA_ARCHIVE_NAMESPACE', 'media_archive__');
|
||||
|
||||
/**
|
||||
* Wrapper for variable_get() using the Media: Archive variable registry.
|
||||
*
|
||||
* @param string $name
|
||||
* The variable name to retrieve. Note that it will be namespaced by
|
||||
* pre-pending MEDIA_ARCHIVE_NAMESPACE, as to avoid variable collisions
|
||||
* with other modules.
|
||||
* @param unknown $default
|
||||
* An optional default variable to return if the variable hasn't been set
|
||||
* yet. Note that within this module, all variables should already be set
|
||||
* in the media_archive_variable_default() function.
|
||||
* @return unknown
|
||||
* Returns the stored variable or its default.
|
||||
*
|
||||
* @see media_archive_variable_set()
|
||||
* @see media_archive_variable_del()
|
||||
* @see media_archive_variable_default()
|
||||
*/
|
||||
function media_archive_variable_get($name, $default = NULL) {
|
||||
// Allow for an override of the default.
|
||||
// Useful when a variable is required (like $path), but namespacing is still
|
||||
// desired.
|
||||
if (!isset($default)) {
|
||||
$default = media_archive_variable_default($name);
|
||||
}
|
||||
// Namespace all variables.
|
||||
$variable_name = MEDIA_ARCHIVE_NAMESPACE . $name;
|
||||
return variable_get($variable_name, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for variable_set() using the Media: Archive variable registry.
|
||||
*
|
||||
* @param string $name
|
||||
* The variable name to set. Note that it will be namespaced by
|
||||
* pre-pending MEDIA_ARCHIVE_NAMESPACE, as to avoid variable collisions with
|
||||
* other modules.
|
||||
* @param unknown $value
|
||||
* The value for which to set the variable.
|
||||
* @return unknown
|
||||
* Returns the stored variable after setting.
|
||||
*
|
||||
* @see media_archive_variable_get()
|
||||
* @see media_archive_variable_del()
|
||||
* @see media_archive_variable_default()
|
||||
*/
|
||||
function media_archive_variable_set($name, $value) {
|
||||
$variable_name = MEDIA_ARCHIVE_NAMESPACE . $name;
|
||||
return variable_set($variable_name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for variable_del() using the Media: Archive variable registry.
|
||||
*
|
||||
* @param string $name
|
||||
* The variable name to delete. Note that it will be namespaced by
|
||||
* pre-pending MEDIA_ARCHIVE_NAMESPACE, as to avoid variable collisions with
|
||||
* other modules.
|
||||
*
|
||||
* @see media_archive_variable_get()
|
||||
* @see media_archive_variable_set()
|
||||
* @see media_archive_variable_default()
|
||||
*/
|
||||
function media_archive_variable_del($name) {
|
||||
$variable_name = MEDIA_ARCHIVE_NAMESPACE . $name;
|
||||
variable_del($variable_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* The default variables within the Media: Archive namespace.
|
||||
*
|
||||
* @param string $name
|
||||
* Optional variable name to retrieve the default. Note that it has not yet
|
||||
* been pre-pended with the MEDIA_ARCHIVE_NAMESPACE namespace at this time.
|
||||
* @return unknown
|
||||
* The default value of this variable, if it's been set, or NULL, unless
|
||||
* $name is NULL, in which case we return an array of all default values.
|
||||
*
|
||||
* @see media_archive_variable_get()
|
||||
* @see media_archive_variable_set()
|
||||
* @see media_archive_variable_del()
|
||||
*/
|
||||
function media_archive_variable_default($name = NULL) {
|
||||
static $defaults;
|
||||
|
||||
if (!isset($defaults)) {
|
||||
$defaults = array(
|
||||
'width' => 560,
|
||||
'height' =>340,
|
||||
'autoplay' => FALSE,
|
||||
'fullscreen' => TRUE,
|
||||
'preview_uri' => 'archive://v/-jubiv7QUco',
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset($name)) {
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
if (isset($defaults[$name])) {
|
||||
return $defaults[$name];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the fully namespace variable name.
|
||||
*
|
||||
* @param string $name
|
||||
* The variable name to retrieve the namespaced name.
|
||||
* @return string
|
||||
* The fully namespace variable name, prepended with
|
||||
* MEDIA_ARCHIVE_NAMESPACE.
|
||||
*/
|
||||
function media_archive_variable_name($name) {
|
||||
return MEDIA_ARCHIVE_NAMESPACE . $name;
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file media_archive/includes/themes/media-archive-video.tpl.php
|
||||
*
|
||||
* Template file for theme('media_archive_video').
|
||||
*
|
||||
* Variables available:
|
||||
* $uri - The uri to the Archive video, such as archive://v/xsy7x8c9.
|
||||
* $video_id - The unique identifier of the Archive video.
|
||||
* $width - The width to render.
|
||||
* $height - The height to render.
|
||||
* $autoplay - If TRUE, then start the player automatically when displaying.
|
||||
* $fullscreen - Whether to allow fullscreen playback.
|
||||
*
|
||||
* Note that we set the width & height of the outer wrapper manually so that
|
||||
* the JS will respect that when resizing later.
|
||||
*/
|
||||
?>
|
||||
<div class="media-archive-outer-wrapper" id="media-archive-<?php print $id; ?>" style="width: <?php print $width; ?>px; height: <?php print $height; ?>px;">
|
||||
<div class="media-archive-preview-wrapper" id="<?php print $wrapper_id; ?>">
|
||||
<?php print $output; ?>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file media_archive/includes/themes/media_archive.theme.inc
|
||||
*
|
||||
* Theme and preprocess functions for Media: Archive.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Preprocess function for theme('media_archive_video').
|
||||
*/
|
||||
function media_archive_preprocess_media_archive_video(&$variables) {
|
||||
// Build the URL for display.
|
||||
$uri = $variables['uri'];
|
||||
$wrapper = file_stream_wrapper_get_instance_by_uri($uri);
|
||||
$parts = $wrapper->get_parameters();
|
||||
$variables['video_id'] = check_plain($parts['v']);
|
||||
|
||||
//convert episode id from filepath to embed code
|
||||
$variables['embed_code'] = media_archive_embedcode_lookup($variables['video_id']);
|
||||
|
||||
$variables['width'] = isset($variables['width']) ? $variables['width'] : media_archive_variable_get('width');
|
||||
$variables['height'] = isset($variables['height']) ? $variables['height'] : media_archive_variable_get('height');
|
||||
$variables['autoplay'] = isset($variables['autoplay']) ? $variables['autoplay'] : media_archive_variable_get('autoplay');
|
||||
$variables['fullscreen'] = isset($variables['fullscreen']) ? $variables['fullscreen'] : media_archive_variable_get('fullscreen');
|
||||
$variables['autoplay'] = $variables['autoplay'] ? 1 : 1;
|
||||
$variables['fullscreen'] = $variables['fullscreen'] ? 'true' : 'false';
|
||||
|
||||
$variables['wrapper_id'] = 'media_archive_' . $variables['video_id'] . '_' . $variables['id'];
|
||||
|
||||
$mp4URL = 'http://www.archive.org/download/' . $variables['video_id'] . '/' . $variables['embed_code'] . '_512kb.mp4';
|
||||
$ogvURL = 'http://www.archive.org/download/' . $variables['video_id'] . '/' . $variables['embed_code'] . '.ogv';
|
||||
|
||||
//Fix for IE!!
|
||||
|
||||
//<object width="640" height="506" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"><param value="true" name="allowfullscreen"/><param value="always" name="allowscriptaccess"/><param value="high" name="quality"/><param value="true" name="cachebusting"/><param value="#000000" name="bgcolor"/><param name="movie" value="http://www.archive.org/flow/flowplayer.commercial-3.2.1.swf" /><param value="config={'key':'#$aa4baff94a9bdcafce8','playlist':['format=Thumbnail?.jpg',{'autoPlay':false,'url':'Domino_Theory_512kb.mp4'}],'clip':{'autoPlay':true,'baseUrl':'http://www.archive.org/download/bavc-77620-dominotheory/','scaling':'fit','provider':'h264streaming'},'canvas':{'backgroundColor':'#000000','backgroundGradient':'none'},'plugins':{'controls':{'playlist':false,'fullscreen':true,'height':26,'backgroundColor':'#000000','autoHide':{'fullscreenOnly':true}},'h264streaming':{'url':'http://www.archive.org/flow/flowplayer.pseudostreaming-3.2.1.swf'}},'contextMenu':[{},'-','Flowplayer v3.2.1']}" name="flashvars"/><embed src="http://www.archive.org/flow/flowplayer.commercial-3.2.1.swf" type="application/x-shockwave-flash" width="640" height="506" allowfullscreen="true" allowscriptaccess="always" cachebusting="true" bgcolor="#000000" quality="high" flashvars="config={'key':'#$aa4baff94a9bdcafce8','playlist':['format=Thumbnail?.jpg',{'autoPlay':false,'url':'Domino_Theory_512kb.mp4'}],'clip':{'autoPlay':true,'baseUrl':'http://www.archive.org/download/bavc-77620-dominotheory/','scaling':'fit','provider':'h264streaming'},'canvas':{'backgroundColor':'#000000','backgroundGradient':'none'},'plugins':{'controls':{'playlist':false,'fullscreen':true,'height':26,'backgroundColor':'#000000','autoHide':{'fullscreenOnly':true}},'h264streaming':{'url':'http://www.archive.org/flow/flowplayer.pseudostreaming-3.2.1.swf'}},'contextMenu':[{},'-','Flowplayer v3.2.1']}"> </embed></object>
|
||||
|
||||
|
||||
$variables['output'] = '<video width="' . $variables['width'] .'" height="' . $variables['height'] .'" controls>
|
||||
<source src="' . $mp4URL . '" type=\'video/mp4; codecs="avc1.42E01E, mp4a.40.2"\'>
|
||||
<source src="' . $ogvURL . '" type=\'video/ogg; codecs="theora, vorbis"\'>
|
||||
</video>';
|
||||
|
||||
// For users with JavaScript, these object and embed tags will be replaced
|
||||
// by an iframe, so that we can support users without Flash.
|
||||
/*
|
||||
$variables['output'] = '<object width="' . $variables['width'] . '" height="' . $variables['height'] . '">';
|
||||
$variables['output'] .= '<param value="true" name="allowfullscreen"/><param value="always" name="allowscriptaccess"/><param value="high" name="quality"/><param value="true" name="cachebusting"/><param value="#000000" name="bgcolor"/>';
|
||||
$variables['output'] .= '<param name="movie" value="http://www.archive.org/flow/flowplayer.commercial-3.2.1.swf"></param>';
|
||||
$variables['output'] .= '<param name="allowFullScreen" value="' . $variables['fullscreen'] . '"></param>';
|
||||
$variables['output'] .= '<param name="wmode" value="transparent" />';
|
||||
|
||||
$variables['output'] .= "<param value=\"config={'key':'#$aa4baff94a9bdcafce8','playlist':['format=Thumbnail?.jpg',{'autoPlay':false,'url':'" . $variables['embed_code'] . "_512kb.mp4'}],'clip':{'autoPlay':true,'baseUrl':'http://www.archive.org/download/bavc-77620-dominotheory/','scaling':'fit','provider':'h264streaming'},'canvas':{'backgroundColor':'#000000','backgroundGradient':'none'},'plugins':{'controls':{'playlist':false,'fullscreen':true,'height':26,'backgroundColor':'#000000','autoHide':{'fullscreenOnly':true}},'h264streaming':{'url':'http://www.archive.org/flow/flowplayer.pseudostreaming-3.2.1.swf'}},'contextMenu':[{},'-','Flowplayer v3.2.1']}\" name=\"flashvars\"/>";
|
||||
|
||||
$config = "'key':\'#$aa4baff94a9bdcafce8','playlist':['format=Thumbnail?.jpg',{'autoPlay':false,'url':'" . $variables['embed_code'] . "_512kb.mp4'}],'clip':{'autoPlay':true,'baseUrl':'http://www.archive.org/download/" . $variables['video_id'] . "/','scaling':'fit','provider':'h264streaming'},'canvas':{'backgroundColor':'#000000','backgroundGradient':'none'},'plugins':{'controls':{'playlist':false,'fullscreen':true,'height':26,'backgroundColor':'#000000','autoHide':{'fullscreenOnly':true}},'h264streaming':{'url':'http://www.archive.org/flow/flowplayer.pseudostreaming-3.2.1.swf'}},'contextMenu':[{},'-','Flowplayer v3.2.1']";
|
||||
|
||||
|
||||
$variables['output'] .= '<embed src="http://www.archive.org/flow/flowplayer.commercial-3.2.1.swf" type="application/x-shockwave-flash" width="' . $variables['width'] . '" height="' . $variables['height'] . '" allowfullscreen="' . $variables['fullscreen'] . 'allowfullscreen="true" allowscriptaccess="always" cachebusting="true" bgcolor="#000000" quality="high" flashvars="config={' . $config . '}"></embed>';
|
||||
$variables['output'] .= '</object>';
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
$variables['output'] = <<<OUTPUT
|
||||
<object width="{$variables['width']}" height="{$variables['height']}">
|
||||
<param name="movie" value="http://www.archive.org/play/{$variables['embed_code']}"></param>
|
||||
<param name="allowFullScreen" value="{$variables['fullscreen']}"></param>
|
||||
<param name="wmode" value="transparent" />
|
||||
<embed src="http://www.archive.org/play/{$variables['embed_code']}" type="application/x-shockwave-flash" width="{$variables['width']}" height="{$variables['height']}" allowfullscreen="{$variables['fullscreen']}"></embed>
|
||||
</object>
|
||||
OUTPUT;
|
||||
*/
|
||||
|
||||
// @todo Replace this inline JavaScript with at least calls to
|
||||
// drupal_add_js()/drupal_get_js(), and ideally, with a behavior. Keep
|
||||
// in mind that the solution needs to work when inside a colorbox or
|
||||
// otherwise in an AJAX response, but that should now be possible in D7.
|
||||
|
||||
/*
|
||||
|
||||
$iframe_id = drupal_json_encode($variables['wrapper_id'] .'_iframe');
|
||||
$wrapper_id = drupal_json_encode($variables['wrapper_id']);
|
||||
$JSObject = 'Drupal.settings.media_archive[' . $wrapper_id . ']';
|
||||
$variables['output'] .= <<<OUTPUT
|
||||
<script type="text/javascript">
|
||||
if (Drupal.settings && Drupal.media_archive) {
|
||||
Drupal.settings.media_archive = Drupal.settings.media_archive || {};
|
||||
$JSObject = {};
|
||||
$JSObject.width = {$variables['width']};
|
||||
$JSObject.height = {$variables['height']};
|
||||
$JSObject.video_id = "{$variables['video_id']}";
|
||||
$JSObject.fullscreen = {$variables['fullscreen']};
|
||||
$JSObject.id = $iframe_id;
|
||||
Drupal.media_archive.insertEmbed($wrapper_id);
|
||||
}
|
||||
</script>
|
||||
OUTPUT;
|
||||
*/
|
||||
|
||||
//drupal_add_js(drupal_get_path('module', 'media_archive') . '/js/media_archive.js');
|
||||
drupal_add_css(drupal_get_path('module', 'media_archive') . '/css/media_archive.css');
|
||||
drupal_add_js(drupal_get_path('module', 'media_archive') . '/js/flash_detect_min.js');
|
||||
}
|
||||
|
||||
function theme_media_archive_field_formatter_styles($variables) {
|
||||
$element = $variables['element'];
|
||||
$style = $variables['style'];
|
||||
$variables['file'] = $element['#item'];
|
||||
$variables['uri'] = $variables['file']['uri'];
|
||||
$variables['style_name'] = $style['name'];
|
||||
return theme('media_archive_embed', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Preview for Styles UI.
|
||||
*/
|
||||
function theme_media_archive_preview_style($variables) {
|
||||
$variables['uri'] = media_archive_variable_get('preview_uri');
|
||||
$variables['field_type'] = 'file';
|
||||
$variables['object'] = file_uri_to_object($variables['uri']);
|
||||
|
||||
return theme('styles', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: Deprecated with Styles version 2.
|
||||
*/
|
||||
function theme_media_archive_styles($variables) {
|
||||
$style = $variables['style'];
|
||||
$variables['file'] = $variables['object'];
|
||||
$variables['uri'] = $variables['object']->uri;
|
||||
$variables['style_name'] = $style['name'];
|
||||
return theme('media_archive_embed', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo: get this working
|
||||
*
|
||||
* This code is for embedding videos in WYSIYWG areas, not currently working.
|
||||
* NOTE: Deprecated with Styles version 2.
|
||||
*/
|
||||
function theme_media_archive_embed($variables) {
|
||||
$preset_name = $variables['preset_name'];
|
||||
$preset = styles_containers_available_styles('file', 'media_archive', $preset_name);
|
||||
$output = '';
|
||||
if (!empty($preset)) {
|
||||
// Build the URL for display.
|
||||
$uri = $variables['uri'];
|
||||
$wrapper = file_stream_wrapper_get_instance_by_uri($uri);
|
||||
$parts = $wrapper->get_parameters();
|
||||
|
||||
$fullscreen_value = $autoplay = 'false';
|
||||
$in_browser = $thumbnail = FALSE;
|
||||
|
||||
foreach ($preset['effects'] as $effect) {
|
||||
switch ($effect['name']) {
|
||||
case 'autoplay':
|
||||
$autoplay = $effect['data']['autoplay'] ? 'true' : 'false';
|
||||
break;
|
||||
case 'resize':
|
||||
$width = $effect['data']['width'];
|
||||
$height = $effect['data']['height'];
|
||||
break;
|
||||
case 'fullscreen':
|
||||
$fullscreen_value = $effect['data']['fullscreen'] ? 'true' : 'false';
|
||||
break;
|
||||
case 'thumbnail':
|
||||
$thumbnail = $effect['data']['thumbnail'];
|
||||
}
|
||||
}
|
||||
if (isset($variables['object']->override)) {
|
||||
$override = $variables['object']->override;
|
||||
if (isset($override['width'])) {
|
||||
$width = $override['width'];
|
||||
}
|
||||
if (isset($override['height'])) {
|
||||
$height = $override['height'];
|
||||
}
|
||||
if (isset($override['wysiwyg'])) {
|
||||
$thumbnail = TRUE;
|
||||
}
|
||||
if (isset($override['browser']) && $override['browser']) {
|
||||
$in_browser = TRUE;
|
||||
$thumbnail = TRUE;
|
||||
}
|
||||
}
|
||||
$width = isset($width) ? $width : media_archive_variable_get('width');
|
||||
$height = isset($height) ? $height : media_archive_variable_get('height');
|
||||
$video_id = check_plain($parts['v']);
|
||||
if ($thumbnail) {
|
||||
// @todo Clean this up.
|
||||
$image_variables = array(
|
||||
'path' => $wrapper->getOriginalThumbnailPath(),
|
||||
'alt' => $variables['alt'],
|
||||
'title' => $variables['title'],
|
||||
'getsize' => FALSE,
|
||||
);
|
||||
if (isset($preset['image_style'])) {
|
||||
$image_variables['path'] = $wrapper->getLocalThumbnailPath();
|
||||
$image_variables['style_name'] = $preset['image_style'];
|
||||
$output = theme('image_style', $image_variables);
|
||||
}
|
||||
else {
|
||||
// We need to add this style attribute here so that it doesn't get lost
|
||||
// If you resize a video in a node, save it, edit it, but don't adjust
|
||||
// the sizing of the video while editing, the size will revert to the
|
||||
// default. Adding the specific size here retains the original resizing
|
||||
$WYSIWYG = isset($variables['object']->override['style']) ? $variables['object']->override['style'] : '';
|
||||
$image_variables['attributes'] = array('width' => $width, 'height' => $height, 'style' => $WYSIWYG);
|
||||
$output = theme('image', $image_variables);
|
||||
}
|
||||
if ($in_browser) {
|
||||
// Add an overlay that says 'Archive' to media library browser thumbnails.
|
||||
$output .= '<span />';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$output = theme('media_archive_video', array('uri' => $uri, 'width' => $width, 'height' => $height, 'autoplay' => ($autoplay == 'true' ? TRUE : NULL), 'fullscreen' => ($fullscreen_value == 'true' ? TRUE : NULL)));
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
5
sites/all/modules/media_archive/js/flash_detect_min.js
Normal file
5
sites/all/modules/media_archive/js/flash_detect_min.js
Normal file
@@ -0,0 +1,5 @@
|
||||
//http://www.featureblend.com/license.txt
|
||||
var FlashDetect=new function(){var self=this;self.installed=false;self.raw="";self.major=-1;self.minor=-1;self.revision=-1;self.revisionStr="";var activeXDetectRules=[{"name":"ShockwaveFlash.ShockwaveFlash.7","version":function(obj){return getActiveXVersion(obj);}},{"name":"ShockwaveFlash.ShockwaveFlash.6","version":function(obj){var version="6,0,21";try{obj.AllowScriptAccess="always";version=getActiveXVersion(obj);}catch(err){}
|
||||
return version;}},{"name":"ShockwaveFlash.ShockwaveFlash","version":function(obj){return getActiveXVersion(obj);}}];var getActiveXVersion=function(activeXObj){var version=-1;try{version=activeXObj.GetVariable("$version");}catch(err){}
|
||||
return version;};var getActiveXObject=function(name){var obj=-1;try{obj=new ActiveXObject(name);}catch(err){obj={activeXError:true};}
|
||||
return obj;};var parseActiveXVersion=function(str){var versionArray=str.split(",");return{"raw":str,"major":parseInt(versionArray[0].split(" ")[1],10),"minor":parseInt(versionArray[1],10),"revision":parseInt(versionArray[2],10),"revisionStr":versionArray[2]};};var parseStandardVersion=function(str){var descParts=str.split(/ +/);var majorMinor=descParts[2].split(/\./);var revisionStr=descParts[3];return{"raw":str,"major":parseInt(majorMinor[0],10),"minor":parseInt(majorMinor[1],10),"revisionStr":revisionStr,"revision":parseRevisionStrToInt(revisionStr)};};var parseRevisionStrToInt=function(str){return parseInt(str.replace(/[a-zA-Z]/g,""),10)||self.revision;};self.majorAtLeast=function(version){return self.major>=version;};self.minorAtLeast=function(version){return self.minor>=version;};self.revisionAtLeast=function(version){return self.revision>=version;};self.versionAtLeast=function(major){var properties=[self.major,self.minor,self.revision];var len=Math.min(properties.length,arguments.length);for(i=0;i<len;i++){if(properties[i]>=arguments[i]){if(i+1<len&&properties[i]==arguments[i]){continue;}else{return true;}}else{return false;}}};self.FlashDetect=function(){if(navigator.plugins&&navigator.plugins.length>0){var type='application/x-shockwave-flash';var mimeTypes=navigator.mimeTypes;if(mimeTypes&&mimeTypes[type]&&mimeTypes[type].enabledPlugin&&mimeTypes[type].enabledPlugin.description){var version=mimeTypes[type].enabledPlugin.description;var versionObj=parseStandardVersion(version);self.raw=versionObj.raw;self.major=versionObj.major;self.minor=versionObj.minor;self.revisionStr=versionObj.revisionStr;self.revision=versionObj.revision;self.installed=true;}}else if(navigator.appVersion.indexOf("Mac")==-1&&window.execScript){var version=-1;for(var i=0;i<activeXDetectRules.length&&version==-1;i++){var obj=getActiveXObject(activeXDetectRules[i].name);if(!obj.activeXError){self.installed=true;version=activeXDetectRules[i].version(obj);if(version!=-1){var versionObj=parseActiveXVersion(version);self.raw=versionObj.raw;self.major=versionObj.major;self.minor=versionObj.minor;self.revision=versionObj.revision;self.revisionStr=versionObj.revisionStr;}}}}}();};FlashDetect.JS_RELEASE="1.0.4";
|
127
sites/all/modules/media_archive/js/media_archive.fromurl.js
Normal file
127
sites/all/modules/media_archive/js/media_archive.fromurl.js
Normal file
@@ -0,0 +1,127 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Create the 'Archive' tab for the WYSIWYG plugins.
|
||||
*/
|
||||
|
||||
// (function ($) {
|
||||
// namespace('Drupal.media.browser.plugin');
|
||||
//
|
||||
// Drupal.media.browser.plugin.media_archive = function(mediaBrowser, options) {
|
||||
// return {
|
||||
// init: function() {
|
||||
// tabset = mediaBrowser.getTabset();
|
||||
// tabset.tabs('add', '#media_archive', 'Archive');
|
||||
// mediaBrowser.listen('tabs.show', function (e, id) {
|
||||
// if (id == 'media_archive') {
|
||||
// // We only need to set this once.
|
||||
// // We probably could set it upon load.
|
||||
// if (mediaBrowser.getActivePanel().html() == '') {
|
||||
// mediaBrowser.getActivePanel().html(options.media_archive);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// // For now, I guess self registration makes sense.
|
||||
// // Really though, we should be doing it via drupal_add_js and some settings
|
||||
// // from the drupal variable.
|
||||
// //@todo: needs a review.
|
||||
// Drupal.media.browser.register('media_archive', Drupal.media.browser.plugin.media_archive, {});
|
||||
// })(jQuery);
|
||||
|
||||
(function ($) {
|
||||
namespace('media.browser.plugin');
|
||||
|
||||
Drupal.media.browser.plugin.archive_library = function(mediaBrowser, options) {
|
||||
|
||||
return {
|
||||
mediaFiles: [],
|
||||
init: function() {
|
||||
tabset = mediaBrowser.getTabset();
|
||||
tabset.tabs('add', '#archive_library', 'Archive');
|
||||
var that = this;
|
||||
mediaBrowser.listen('tabs.show', function (e, id) {
|
||||
if (id == 'archive_library') {
|
||||
// This is kinda rough, I'm not sure who should delegate what here.
|
||||
mediaBrowser.getActivePanel().addClass('throbber');
|
||||
mediaBrowser.getActivePanel().html('');
|
||||
//mediaBrowser.getActivePanel().addClass('throbber');
|
||||
|
||||
// Assumes we have to refresh everytime.
|
||||
// Remove any existing content
|
||||
mediaBrowser.getActivePanel().append('<ul></ul>');
|
||||
that.browser = $('ul', mediaBrowser.getActivePanel());
|
||||
that.browser.addClass('clearfix');
|
||||
that.getMedia();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getStreams: function () {
|
||||
return ['archive://'];
|
||||
},
|
||||
|
||||
getConditions: function () {
|
||||
return {};
|
||||
//return this.settings.conditions;
|
||||
},
|
||||
|
||||
getMedia: function() {
|
||||
var that = this;
|
||||
var callback = mediaBrowser.getCallbackUrl('getMedia');
|
||||
var params = {
|
||||
conditions: JSON.stringify(this.getConditions()),
|
||||
streams: JSON.stringify(this.getStreams())
|
||||
};
|
||||
jQuery.get(
|
||||
callback,
|
||||
params,
|
||||
function(data, status) {
|
||||
that.mediaFiles = data.media;
|
||||
that.emptyMessage = data.empty;
|
||||
that.pager = data.pager;
|
||||
that.render();
|
||||
},
|
||||
'json'
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var that = this;
|
||||
mediaBrowser.getActivePanel().removeClass('throbber');
|
||||
if (this.mediaFiles.length < 1) {
|
||||
jQuery('<div id="media-empty-message" class="media-empty-message"></div>').appendTo(this.browser)
|
||||
.html(this.emptyMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var m in this.mediaFiles) {
|
||||
mediaFile = this.mediaFiles[m];
|
||||
|
||||
var listItem = jQuery('<li></li>').appendTo(this.browser)
|
||||
.attr('id', 'media-file-' + mediaFile.fid)
|
||||
.addClass('media-file');
|
||||
|
||||
var imgLink = jQuery('<a href="#"></a>').appendTo(listItem)
|
||||
.html(mediaFile.preview)
|
||||
.bind('click', mediaFile, function(e) {
|
||||
// Notify the main browser
|
||||
//this.selectedMedia = mediaFile;
|
||||
$('div.media-thumbnail img').removeClass('selected');
|
||||
$('div.media-thumbnail img', $(this)).addClass('selected');
|
||||
mediaBrowser.notify('mediaSelected', {mediaFiles: [e.data]});
|
||||
//that.settings.onSelect(mediaFile);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
jQuery('<div id="media-pager" class="media-pager"></div>').appendTo(this.browser)
|
||||
.html(this.pager);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Drupal.media.browser.register('archive_library', Drupal.media.browser.plugin.archive_library);
|
||||
})(jQuery);
|
99
sites/all/modules/media_archive/js/media_archive.js
Normal file
99
sites/all/modules/media_archive/js/media_archive.js
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
/**
|
||||
* @file media_archive/js/media_archive.js
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
|
||||
Drupal.media_archive = {};
|
||||
Drupal.behaviors.media_archive = {
|
||||
attach: function (context, settings) {
|
||||
// Check the browser to see if it supports html5 video.
|
||||
var video = document.createElement('video');
|
||||
var html5 = video.canPlayType ? true : false;
|
||||
|
||||
// If it has video, does it support the correct codecs?
|
||||
if (html5) {
|
||||
html5 = false;
|
||||
if (video.canPlayType( 'video/webm; codecs="vp8, vorbis"' ) || video.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')) {
|
||||
html5 = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Put a prompt in the video wrappers to let users know they need flash
|
||||
if (!FlashDetect.installed && !html5){
|
||||
$('.media-archive-preview-wrapper').each(Drupal.media_archive.needFlash);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.media_archive.needFlash = function () {
|
||||
var id = $(this).attr('id');
|
||||
var wrapper = $('.media-archive-preview-wrapper');
|
||||
var hw = Drupal.settings.media_archive[id].height / Drupal.settings.media_archive[id].width;
|
||||
wrapper.html('<div class="js-fallback">' + Drupal.t('You need Flash to watch this video. <a href="@flash">Get Flash</a>', {'@flash':'http://get.adobe.com/flashplayer'}) + '</div>');
|
||||
wrapper.height(wrapper.width() * hw);
|
||||
};
|
||||
|
||||
Drupal.media_archive.insertEmbed = function (embed_id) {
|
||||
var videoWrapper = $('#' + embed_id + '.media-archive-preview-wrapper');
|
||||
var settings = Drupal.settings.media_archive[embed_id];
|
||||
|
||||
// Calculate the ratio of the dimensions of the embed.
|
||||
settings.hw = settings.height / settings.width;
|
||||
|
||||
// Replace the object embed with Archive's iframe. This isn't done by the
|
||||
// theme function because Archive doesn't have a no-JS or no-Flash fallback.
|
||||
var video = $('<iframe class="archive-player" type="text/html" frameborder="0"></iframe>');
|
||||
var src = 'http://www.archive.org/file/' + settings.video_id;
|
||||
|
||||
// Allow other modules to modify the video settings.
|
||||
settings.options = {wmode : 'opaque'};
|
||||
$(window).trigger('media_archive_load', settings);
|
||||
|
||||
// Merge Archive options (such as autoplay) into the source URL.
|
||||
var query = $.param(settings.options);
|
||||
if (query) {
|
||||
src += '?' + query;
|
||||
}
|
||||
|
||||
// Set up the iframe with its contents and add it to the page.
|
||||
video
|
||||
.attr('id', settings.id)
|
||||
.attr('width', settings.width)
|
||||
.attr('height', settings.height)
|
||||
.attr('src', src);
|
||||
videoWrapper.html(video);
|
||||
|
||||
// Bind a resize event to handle fluid layouts.
|
||||
$(window).bind('resize', Drupal.media_archive.resizeEmbeds);
|
||||
|
||||
// For some reason Chrome does not properly size the container around the
|
||||
// embed and it will just render the embed at full size unless we set this
|
||||
// timeout.
|
||||
if (!$('.lightbox-stack').length) {
|
||||
setTimeout(Drupal.media_archive.resizeEmbeds, 1);
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.media_archive.resizeEmbeds = function () {
|
||||
$('.media-archive-preview-wrapper').each(Drupal.media_archive.resizeEmbed);
|
||||
};
|
||||
|
||||
Drupal.media_archive.resizeEmbed = function () {
|
||||
var context = $(this).parent();
|
||||
var video = $(this).children(':first-child');
|
||||
var hw = Drupal.settings.media_archive[$(this).attr('id')].hw;
|
||||
// Change the height of the wrapper that was given a fixed height by the
|
||||
// Archive theming function.
|
||||
$(this)
|
||||
.height(context.width() * hw)
|
||||
.width(context.width());
|
||||
|
||||
// Change the attributes on the embed to match the new size.
|
||||
video
|
||||
.height(context.width() * hw)
|
||||
.width(context.width());
|
||||
};
|
||||
|
||||
})(jQuery);
|
113
sites/all/modules/media_archive/media_archive.admin.inc
Normal file
113
sites/all/modules/media_archive/media_archive.admin.inc
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Administrative page callbacks for Media: Archive.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback for /media/add/media_archive and
|
||||
* /admin/content/media/add/media_archive.
|
||||
*/
|
||||
function media_archive_add($form, &$form_state = array(), $redirect = NULL) {
|
||||
global $user;
|
||||
|
||||
$form = array();
|
||||
$form['archive'] = array(
|
||||
'#type' => 'vertical_tabs',
|
||||
);
|
||||
$form['archive']['all'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('All Archive videos'),
|
||||
);
|
||||
|
||||
// Get all archive files for this user
|
||||
$results = db_query("SELECT fid FROM {file_managed} WHERE uid = :uid AND uri LIKE :uri", array(
|
||||
':uid' => $user->uid,
|
||||
':uri' => 'archive%%'
|
||||
))->fetchAll();
|
||||
|
||||
foreach ($results as $result) {
|
||||
$file = file_load($result->fid);
|
||||
$output = theme('image', array(
|
||||
'path' => 'http://img.archive.org/vi/' . pathinfo($file->uri, PATHINFO_FILENAME) . '/0.jpg',
|
||||
'title' => 'title',
|
||||
'alt' => 'alt',
|
||||
'attributes' => array('width' => 150),
|
||||
'getsize' => FALSE,
|
||||
));
|
||||
$form['archive']['all'][$file->fid] = array(
|
||||
'#markup' => $output,
|
||||
);
|
||||
}
|
||||
|
||||
/* $form['archive']['all']['test'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => 'test',
|
||||
);*/
|
||||
$form['archive']['add_from_url'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Add from URL'),
|
||||
);
|
||||
$form['archive']['add_from_url']['url'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => 'URL',
|
||||
'#description' => 'Input the URL of the desired Archive video page.',
|
||||
);
|
||||
$form['redirect'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $redirect,
|
||||
);
|
||||
$form['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => 'Submit',
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation for media_archive_add().
|
||||
*/
|
||||
function media_archive_add_validate($form, &$form_state) {
|
||||
if (!preg_match('@blip\.tv/file/([^"\& ]+)@i', $form_state['values']['url'], $matches)) {
|
||||
form_set_error('url', t('Please submit a valid Archive video URL.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submission for media_archive_add().
|
||||
*
|
||||
* This will create a file object for the Archive video.
|
||||
*/
|
||||
function media_archive_add_submit($form, &$form_state) {
|
||||
$defaults = array (
|
||||
'display' => TRUE,
|
||||
);
|
||||
|
||||
$uri = media_archive_media_parse($form_state['values']['url']);
|
||||
|
||||
// Check to see if this a duplicate of an existing file
|
||||
$files = file_load_multiple(NULL, array('uri' => $uri));
|
||||
if ($files) {
|
||||
// This is ugly.
|
||||
$file = array_shift($files);
|
||||
}
|
||||
else {
|
||||
// @TODO: This won't work for Archive and many other streams.
|
||||
// copy($url, $destination);
|
||||
$file = file_uri_to_object($uri);
|
||||
file_save($file);
|
||||
}
|
||||
|
||||
// field_attach_insert('media', $file);
|
||||
if ($file) {
|
||||
$form_state['redirect'] = 'media/' . $file->fid . '/edit';
|
||||
field_attach_submit('media', $file, $form, $form_state);
|
||||
field_attach_insert('media', $file);
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('An error occurred and no file was saved.'), 'error');
|
||||
}
|
||||
|
||||
$form_state['redirect'] = !empty($form_state['values']['redirect']) ? $form_state['values']['redirect'] : 'media/' . $file->fid . '/edit';
|
||||
}
|
17
sites/all/modules/media_archive/media_archive.info
Normal file
17
sites/all/modules/media_archive/media_archive.info
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
name = Media: Archive
|
||||
description = Provides Archive support to the Media module.
|
||||
package = "Media"
|
||||
core = 7.x
|
||||
files[] = media_archive.module
|
||||
files[] = MediaArchiveStreamWrapper.inc
|
||||
files[] = media_archive.admin.inc
|
||||
files[] = includes/media_archive.styles.inc
|
||||
dependencies[] = media_internet
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-05-31
|
||||
version = "7.x-1.0-beta1"
|
||||
core = "7.x"
|
||||
project = "media_archive"
|
||||
datestamp = "1306873316"
|
||||
|
24
sites/all/modules/media_archive/media_archive.install
Normal file
24
sites/all/modules/media_archive/media_archive.install
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the Media: Archive module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implement hook_install().
|
||||
*/
|
||||
function media_archive_install() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement hook_uninstall().
|
||||
*/
|
||||
function media_archive_uninstall() {
|
||||
foreach (media_archive_variable_default() as $variable => $value) {
|
||||
media_archive_variable_del($variable);
|
||||
}
|
||||
return array(array('success' => TRUE, 'query' => "Deleted all variables in the Media: Archive namespace."));
|
||||
}
|
||||
|
352
sites/all/modules/media_archive/media_archive.module
Normal file
352
sites/all/modules/media_archive/media_archive.module
Normal file
@@ -0,0 +1,352 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file media_archive/media_archive.module
|
||||
*
|
||||
* Media: Archive provides a stream wrapper and formatters for videos provided
|
||||
* by Archive, available at http://archive.org/.
|
||||
*
|
||||
* @TODO:
|
||||
* Tie in Archive API.
|
||||
* Allow editors to search for videos to display on the browser.
|
||||
* Allow editors to put in a archive username to display on the browser.
|
||||
* Allow editors to log in w/ their credentials.
|
||||
* Allow editors to upload videos to Archive.
|
||||
*/
|
||||
|
||||
// A registry of variable_get defaults.
|
||||
include_once('includes/media_archive.variables.inc');
|
||||
|
||||
/**
|
||||
* Create stream wrapper for Archive videos.
|
||||
*/
|
||||
function media_archive_stream_wrappers() {
|
||||
return array(
|
||||
'archive' => array(
|
||||
'name' => t('Archive videos'),
|
||||
'class' => 'MediaArchiveStreamWrapper',
|
||||
'description' => t('Videos provided by Archive.'),
|
||||
'type' => STREAM_WRAPPERS_READ_VISIBLE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function media_archive_media_format_form_prepare_alter(&$form, &$form_state, $media) {
|
||||
$settings = array('autosubmit' => ($media->type == "video"));
|
||||
drupal_add_js(array('media_format_form' => $settings), 'setting');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function media_archive_theme($existing, $type, $theme, $path) {
|
||||
return array(
|
||||
'media_archive_preview_style' => array(
|
||||
'variables' => array('style_name' => NULL),
|
||||
'file' => 'media_archive.theme.inc',
|
||||
'path' => $path . '/includes/themes',
|
||||
),
|
||||
'media_archive_field_formatter_styles' => array(
|
||||
'variables' => array('element' => NULL, 'style' => NULL),
|
||||
'file' => 'media_archive.theme.inc',
|
||||
'path' => $path . '/includes/themes',
|
||||
),
|
||||
'media_archive_video' => array(
|
||||
'variables' => array('uri' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL, 'fullscreen' => NULL),
|
||||
'file' => 'media_archive.theme.inc',
|
||||
'path' => $path . '/includes/themes',
|
||||
'template' => 'media-archive-video',
|
||||
),
|
||||
'media_archive_embed' => array(
|
||||
'variables' => array('style_name' => NULL, 'uri' => NULL, 'alt' => NULL, 'title' => NULL),
|
||||
'file' => 'media_archive.theme.inc',
|
||||
'path' => $path . '/includes/themes',
|
||||
),
|
||||
'media_archive_styles' => array(
|
||||
'variables' => array('element' => NULL, 'style' => NULL),
|
||||
'file' => 'media_archive.theme.inc',
|
||||
'path' => $path . '/includes/themes',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of Styles module hook_styles_register().
|
||||
*/
|
||||
function media_archive_styles_register() {
|
||||
return array(
|
||||
'MediaArchiveStyles' => array(
|
||||
'field_types' => 'file',
|
||||
'name' => t('MediaArchive'),
|
||||
'description' => t('Media Archive styles.'),
|
||||
'path' => drupal_get_path('module', 'media_archive') .'/includes',
|
||||
'file' => 'media_archive.styles.inc',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_styles_containers(). (Deprecated in version 2)
|
||||
*/
|
||||
function media_archive_styles_containers() {
|
||||
return array(
|
||||
'file' => array(
|
||||
'containers' => array(
|
||||
'media_archive' => array(
|
||||
'label' => t('Archive Styles'),
|
||||
'data' => array(
|
||||
'streams' => array(
|
||||
'archive',
|
||||
),
|
||||
'mimetypes' => array(
|
||||
'video/archive',
|
||||
),
|
||||
),
|
||||
'weight' => 0,
|
||||
'filter callback' => 'media_archive_formatter_filter',
|
||||
'themes' => array(
|
||||
'field_formatter_styles' => 'media_archive_field_formatter_styles',
|
||||
'styles' => 'media_archive_styles',
|
||||
'preview' => 'media_archive_preview_style',
|
||||
),
|
||||
'description' => t('Archive Styles will display embedded Archive videos and thumbnails to your choosing, such as by resizing, setting colors, and autoplay. You can !manage.', array('!manage' => l(t('manage your Archive styles here'), 'admin/config/media/media-archive-styles'))),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function media_archive_formatter_filter($variables) {
|
||||
if (isset($variables['object'])) {
|
||||
$object = $variables['object'];
|
||||
return (file_uri_scheme($object->uri) == 'archive') && ($object->filemime == 'video/archive');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the File Styles module's hook_file_styles_filter().
|
||||
*/
|
||||
function media_archive_file_styles_filter($object) {
|
||||
if ((file_uri_scheme($object->uri) == 'archive') && ($object->filemime == 'video/archive')) {
|
||||
return 'media_archive';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_styles_styles().
|
||||
*/
|
||||
function media_archive_styles_styles() {
|
||||
$styles = array(
|
||||
'file' => array(
|
||||
'containers' => array(
|
||||
'media_archive' => array(
|
||||
'styles' => array(
|
||||
'archive_thumbnail' => array(
|
||||
'name' => 'archive_thumbnail',
|
||||
'effects' => array(
|
||||
array('label' => t('Thumbnail'), 'name' => 'thumbnail', 'data' => array('thumbnail' => 1)),
|
||||
array('label' => t('Resize'), 'name' => 'resize', 'data' => array('width' => 100, 'height' => 75)),
|
||||
),
|
||||
),
|
||||
'archive_preview' => array(
|
||||
'name' => 'archive_preview',
|
||||
'effects' => array(
|
||||
array('label' => t('Autoplay'), 'name' => 'autoplay', 'data' => array('autoplay' => 1)),
|
||||
array('label' => t('Resize'), 'name' => 'resize', 'data' => array('width' => 220, 'height' => 165)),
|
||||
),
|
||||
),
|
||||
'archive_full' => array(
|
||||
'name' => 'archive_full',
|
||||
'effects' => array(
|
||||
array('label' => t('Autoplay'), 'name' => 'autoplay', 'data' => array('autoplay' => 0)),
|
||||
array('label' => t('Resize'), 'name' => 'resize', 'data' => array('width' => 640, 'height' => 480)),
|
||||
array('label' => t('Full screen'), 'name' => 'fullscreen', 'data' => array('fullscreen' => 1)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Allow any image style to be applied to the thumbnail.
|
||||
foreach (image_styles() as $style_name => $image_style) {
|
||||
$styles['file']['containers']['media_archive']['styles']['archive_thumbnail_' . $style_name] = array(
|
||||
'name' => 'archive_thumbnail_' . $style_name,
|
||||
'image_style' => $style_name,
|
||||
'effects' => array(
|
||||
array('label' => t('Thumbnail'), 'name' => 'thumbnail', 'data' => array('thumbnail' => 1)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_styles_presets().
|
||||
*/
|
||||
function media_archive_styles_presets() {
|
||||
$presets = array(
|
||||
'file' => array(
|
||||
'square_thumbnail' => array(
|
||||
'media_archive' => array(
|
||||
'archive_thumbnail_square_thumbnail',
|
||||
),
|
||||
),
|
||||
'thumbnail' => array(
|
||||
'media_archive' => array(
|
||||
'archive_thumbnail',
|
||||
),
|
||||
),
|
||||
'small' => array(
|
||||
'media_archive' => array(
|
||||
'archive_preview',
|
||||
),
|
||||
),
|
||||
'large' => array(
|
||||
'media_archive' => array(
|
||||
'archive_full',
|
||||
),
|
||||
),
|
||||
'original' => array(
|
||||
'media_archive' => array(
|
||||
'archive_full',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $presets;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_media_parse().
|
||||
*
|
||||
* @todo: this might be deprecated now that we have media_internet,
|
||||
* but the hook is still being called in a couple places in media.
|
||||
*/
|
||||
function media_archive_media_parse($url, $options = array()) {
|
||||
$scheme = 'archive://';
|
||||
preg_match('@archive\.org/details/([^"\& ]+)@i', $url, $matches);
|
||||
|
||||
|
||||
if (isset($matches[1])) {
|
||||
$org = media_archive_embedcode_lookup($matches[1]);
|
||||
return file_stream_wrapper_uri_normalize($scheme . 'v/' . $matches[1] . '/org/' . $org);
|
||||
}
|
||||
// @TODO: Validate for malformed archive urls.
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_media_internet_providers();
|
||||
*/
|
||||
function media_archive_media_internet_providers() {
|
||||
$path = drupal_get_path('module', 'media_archive');
|
||||
return array(
|
||||
'MediaInternetArchiveHandler' => array(
|
||||
'title' => 'archive',
|
||||
'image' => $path . '/images/stream-archive.png'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class MediaInternetArchiveHandler extends MediaInternetBaseHandler {
|
||||
public function claim($embedCode) {
|
||||
if (media_archive_media_parse($embedCode)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
public function validate() {
|
||||
// @todo Media module currently fails when two files try to have the same
|
||||
// URI, so catch that in the validation step. Some day, it would be nice
|
||||
// to allow it, however. See http://drupal.org/node/952422.
|
||||
$uri = media_archive_media_parse($this->embedCode);
|
||||
$existing_files = file_load_multiple(array(), array('uri' => $uri));
|
||||
if (count($existing_files)) {
|
||||
throw new MediaInternetValidationException(t('You have entered a URL for a video that is already in your library.'));
|
||||
}
|
||||
}
|
||||
|
||||
public function save() {
|
||||
$file = $this->getFileObject();
|
||||
file_save($file);
|
||||
return $file;
|
||||
}
|
||||
|
||||
public function getFileObject() {
|
||||
$uri = media_archive_media_parse($this->embedCode);
|
||||
//@todo: this is terribly broken in some ways because the function is really
|
||||
// made for local files which are 'real'
|
||||
return file_uri_to_object($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the media. See http://video.search.yahoo.com/mrss.
|
||||
*
|
||||
* @return
|
||||
* If ATOM+MRSS information is available, a SimpleXML element containing
|
||||
* ATOM and MRSS elements, as per those respective specifications.
|
||||
*
|
||||
* @todo Would be better for the return value to be an array rather than a
|
||||
* SimpleXML element, but media_retrieve_xml() needs to be upgraded to
|
||||
* handle namespaces first.
|
||||
*/
|
||||
|
||||
//http://archive.org/file/4035623?skin=rss
|
||||
|
||||
public function getMRSS() {
|
||||
$uri = media_archive_media_parse($this->embedCode);
|
||||
$video_id = arg(1, file_uri_target($uri));
|
||||
$rss_url = url('http://gdata.archive.org/feeds/api/videos/' . $video_id, array('query' => array('v' => '2')));
|
||||
// @todo Use media_retrieve_xml() once it's upgraded to include elements
|
||||
// from all namespaces, not just the document default namespace.
|
||||
$entry = simplexml_load_file($rss_url);
|
||||
return $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the media. See http://www.oembed.com/.
|
||||
*
|
||||
* @return
|
||||
* If oEmbed information is available, an array containing 'title', 'type',
|
||||
* 'url', and other information as specified by the oEmbed standard.
|
||||
* Otherwise, NULL.
|
||||
*/
|
||||
|
||||
//http://archive.org/oembed/?url=http://archive.org/file/12345
|
||||
|
||||
public function getOEmbed() {
|
||||
$uri = media_archive_media_parse($this->embedCode);
|
||||
$external_url = drupal_realpath($uri);
|
||||
$oembed_url = url('http://archive.org/oembed', array('query' => array('url' => $external_url, 'format' => 'json')));
|
||||
$response = drupal_http_request($oembed_url);
|
||||
if (!isset($response->error)) {
|
||||
return drupal_json_decode($response->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function media_archive_embedcode_lookup($video_id) {
|
||||
|
||||
//http://www.archive.org/download/bavc-77620-dominotheory/bavc-77620-dominotheory_files.xml
|
||||
|
||||
//<original>Domino_Theory.mpeg</original>
|
||||
|
||||
// I hate this, but after reading http://data.agaric.com/node/2378 I'm
|
||||
// begining to think there isn't an easier way
|
||||
// if there isn't a better way, this needs to be done once and stored
|
||||
$url = 'http://www.archive.org/download/' . $video_id . '/' . $video_id;
|
||||
$rss_source = $url . '_files.xml';
|
||||
$rss = file_get_contents($rss_source);
|
||||
|
||||
preg_match('/<original>(.+)<\/original>/', $rss, $matches);
|
||||
|
||||
if (isset($matches[1])) {
|
||||
$info = pathinfo($matches[1]);
|
||||
$file_name = basename($matches[1],'.'.$info['extension']);
|
||||
return $file_name;
|
||||
}
|
||||
}
|
30
sites/all/modules/media_archive/media_archive.wysiwyg.css
Normal file
30
sites/all/modules/media_archive/media_archive.wysiwyg.css
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Overlay for Archive thumbnails in the media library browser.
|
||||
*/
|
||||
#media-browser .styles-container-media_archive {
|
||||
/* Relative wrapper for the overlay. */
|
||||
position: relative;
|
||||
}
|
||||
#media-browser .styles-container-media_archive span {
|
||||
/* Here's the overlay image. */
|
||||
background: url(images/stream-archive.png) no-repeat;
|
||||
|
||||
/* Absolute positioning in the relative wrapper creates the overlay. */
|
||||
position: absolute;
|
||||
|
||||
/* Size of the overlay */
|
||||
width: 69px;
|
||||
height: 22px;
|
||||
|
||||
/* Position of the overlay */
|
||||
left: 33px;
|
||||
top: 80px;
|
||||
}
|
||||
#media-browser .styles-container-media_archive span:hover {
|
||||
/* The */
|
||||
background-position: 0px -22px;
|
||||
}
|
||||
#media-browser .styles-container-media_archive img {
|
||||
}
|
@@ -0,0 +1,359 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This include processes archive.org audio files for use with Embedded Media Field.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the main URL for your provider.
|
||||
*/
|
||||
define('EMAUDIO_ARCHIVE_MAIN_URL', 'http://www.archive.org/');
|
||||
|
||||
/**
|
||||
* This is the URL to the API of your provider, if this exists.
|
||||
*/
|
||||
define('EMAUDIO_ARCHIVE_API_URL', 'http://www.google.com/search?q=archive.org+api');
|
||||
|
||||
/**
|
||||
* This defines the version of the content data array that we serialize
|
||||
* in emaudio_archive_data(). If we change the expected keys of that array,
|
||||
* we must increment this value, which will allow older content to be updated
|
||||
* to the new version automatically.
|
||||
*/
|
||||
define('EMAUDIO_ARCHIVE_DATA_VERSION', 2);
|
||||
|
||||
/**
|
||||
* hook emaudio_PROVIDER_info
|
||||
* This returns information relevant to a specific 3rd party audio provider.
|
||||
*
|
||||
* @return
|
||||
* A keyed array of strings requested by various admin and other forms.
|
||||
* 'provider' => The machine name of the provider. This must be the same as
|
||||
* the base name of this filename, before the .inc extension.
|
||||
* 'name' => The translated name of the provider.
|
||||
* 'url' => The url to the main page for the provider.
|
||||
* 'settings_description' => A description of the provider that will be
|
||||
* posted in the admin settings form.
|
||||
* 'supported_features' => An array of rows describing the state of certain
|
||||
* supported features by the provider. These will be rendered in a table,
|
||||
* with the columns being 'Feature', 'Supported', 'Notes'. In general,
|
||||
* the 'Feature' column will give the name of the feature, 'Supported'
|
||||
* will be Yes or No, and 'Notes' will give an optional description or
|
||||
* caveats to the feature.
|
||||
*/
|
||||
function emaudio_archive_audio_info() {
|
||||
$features = array(
|
||||
array(t('Thumbnails'), t('No'), ''),
|
||||
array(t('Autoplay'), t('Yes'), ''),
|
||||
array(t('RSS attachment'), t('No'), ''),
|
||||
);
|
||||
return array(
|
||||
'provider' => 'archive_audio',
|
||||
'name' => t('Archive'),
|
||||
'url' => EMAUDIO_ARCHIVE_MAIN_URL,
|
||||
'settings_description' => t('These settings specifically affect audio played from !archive. You can also read more about its !api.', array('!archive' => l(t('Archive.com'), EMAUDIO_ARCHIVE_MAIN_URL), '!api' => l(t("developer's API"), EMAUDIO_ARCHIVE_API_URL))),
|
||||
'supported_features' => $features,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emaudio_PROVIDER_settings
|
||||
* This should return a subform to be added to the emaudio_settings() admin
|
||||
* settings page.
|
||||
*
|
||||
* Note that a form field set will already be provided at $form['archive'],
|
||||
* so if you want specific provider settings within that field set, you should
|
||||
* add the elements to that form array element.
|
||||
*/
|
||||
function emaudio_archive_audio_settings() {
|
||||
/* No Settings for this provider */
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emaudio_PROVIDER_extract
|
||||
*
|
||||
* This is called to extract the audio code from a pasted URL or embed code.
|
||||
*
|
||||
* We'll be passed a URL or the embed code from a audio when an editor pastes
|
||||
* that in the field's textfield. We'll need to either pass back an array of
|
||||
* regex expressions to match, or do the matching ourselves and return the
|
||||
* resulting audio code.
|
||||
*
|
||||
* @param $parse
|
||||
* An optional string with the pasted URL or embed code.
|
||||
* @return
|
||||
* Either an array of regex expressions to be tested, or a string with the
|
||||
* audio code to be used. If the hook tests the code itself, it should
|
||||
* return either the string of the audio code (if matched), or an empty
|
||||
* array. Otherwise, the calling function will handle testing the embed code
|
||||
* against each regex string in the returned array.
|
||||
*/
|
||||
function emaudio_archive_audio_extract($parse = '') {
|
||||
// Here we assume that a URL will be passed in the form of
|
||||
// http://www.archive.org/details/text-audio-title
|
||||
// or embed code in the form of
|
||||
//<embed ... "playlist":[{"url":"http://www.archive.org/download/text-audio-title/...
|
||||
|
||||
// We'll simply return an array of regular expressions for Embedded Media
|
||||
// Field to handle for us.
|
||||
return array(
|
||||
//In the URL the archive.org item id will appear after "details/" in the URL
|
||||
'@archive\.org\/details\/([^\"\&]+)@i',
|
||||
|
||||
// Now we test for embedded audio code, which is similar in this case to
|
||||
// the above expression, except the item id will appear after "download/"
|
||||
'@archive\.org/download/([^/]+)@i',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement hook emaudio_PROVIDER_data_version().
|
||||
*/
|
||||
function emaudio_archive_audio_data_version() {
|
||||
return EMAUDIO_ARCHIVE_DATA_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emaudio_PROVIDER_data
|
||||
*
|
||||
* Provides an array to be serialised and made available with $item elsewhere.
|
||||
*
|
||||
* This data can be used to store any extraneous information available
|
||||
* specifically to the archive provider.
|
||||
*/
|
||||
function emaudio_archive_audio_data($field, $item, $error_field = '') {
|
||||
|
||||
// Initialize the data array.
|
||||
$data = array();
|
||||
|
||||
// Create some version control. Thus if we make changes to the data array
|
||||
// down the road, we can respect older content. If allowed by Embedded Media
|
||||
// Field, any older content will automatically update this array as needed.
|
||||
// In any case, you should account for the version if you increment it.
|
||||
$data['emaudio_archive_version'] = EMAUDIO_ARCHIVE_DATA_VERSION;
|
||||
|
||||
// Construct a base item url
|
||||
$item_url = "http://www.archive.org/details/". $item['value'];
|
||||
|
||||
// We will leverage the JSON archive.org api to get details about this item
|
||||
// See http://www.archive.org/help/json.php
|
||||
$xml_meta_url = $item_url .'&output=json';
|
||||
$xml_meta = media_archive_request_xml('archive', $xml_meta_url, array(), TRUE, TRUE, $item['value'] .'_meta', FALSE, TRUE);
|
||||
if ($xml_meta['stat'] == 'error' || empty($xml_meta)) {
|
||||
drupal_set_message('This item\'s details cannot be retrieved. The audio can not be displayed.');
|
||||
return $data;
|
||||
}
|
||||
else {
|
||||
$data['details'] = $xml_meta;
|
||||
$server_url = $data['details']['server'] . $data['details']['dir'];
|
||||
}
|
||||
|
||||
$item_files = $data['details']['files'];
|
||||
|
||||
if (!$item_files) {
|
||||
form_set_error($error_field, 'The list of files for the item at archive.org could not be retrieved. The audio can not be displayed.');
|
||||
return $data;
|
||||
}
|
||||
|
||||
//Putting the $key (which is actually the file name) as an element of the
|
||||
//array too for convenience later.
|
||||
foreach ($item_files as $key => $value) {
|
||||
$item_files[$key]['name'] = $key;
|
||||
}
|
||||
|
||||
//Get playlist files only (.m3u files)
|
||||
$files_playlists = array_filter($item_files, "_archive_audio_isplaylist");
|
||||
|
||||
//If there is no playlist then fail
|
||||
if (is_null($files_playlists)) {
|
||||
form_set_error($error_field, 'This archive.org item does not appear to have a playlist.');
|
||||
return $data;
|
||||
}
|
||||
|
||||
//We'll custom sort the array so we'll get first VBR playlists, then other
|
||||
//playlists sorted by highest bitrate. Goal is to present the highest
|
||||
//bitrate playlist offered for this item.
|
||||
$data['playlists'] = $files_playlists;
|
||||
$worked = uasort($files_playlists, "_archive_audio_playlistsort");
|
||||
$candidate_playlist = array_shift($files_playlists);
|
||||
$data['playlist_file_used'] = $candidate_playlist;
|
||||
|
||||
//Retrieve the playlist
|
||||
$result = drupal_http_request('http://' . $server_url . $candidate_playlist['name']);
|
||||
if (!empty($result->error)) {
|
||||
form_set_error($error_field, 'The playlist for the item at archive.org could not be retrieved. The audio can not be displayed.');
|
||||
return $data;
|
||||
}
|
||||
$playlist = $result->data;
|
||||
//We'll store it in the data element as it is used in our theme function to
|
||||
//output the player later.
|
||||
$data['playlist'] = explode("\n", trim($playlist));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort playlist files
|
||||
*/
|
||||
function _archive_audio_playlistsort($file1, $file2) {
|
||||
$components1 = explode(" ", $file1['format']);
|
||||
$components2 = explode(" ", $file2['format']);
|
||||
if ($components1[0] == $components2[0]) {
|
||||
return 0;
|
||||
}
|
||||
//We'll prefer the Variable Bitrate (VBR)
|
||||
elseif ($components1[0] == "VBR") {
|
||||
return -1;
|
||||
}
|
||||
elseif ($components2[0] == "VBR") {
|
||||
return 1;
|
||||
}
|
||||
//Otherwise we'll look for the highest bitrate playlist
|
||||
$br1 = (int)$components1[0];
|
||||
$br2 = (int)$components2[0];
|
||||
if ($br1 > $br2) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this file a playlist (.m3u) file?
|
||||
*/
|
||||
function _archive_audio_isplaylist($file) {
|
||||
if (substr($file['format'], -3, 3) == "M3U") {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emfield_PROVIDER_rss
|
||||
*/
|
||||
function emaudio_archive_audio_rss($item, $teaser = NULL) {
|
||||
// Get size and mime type of first playlist file
|
||||
$url = $item['data']['playlist'][0];
|
||||
$response = emfield_request_header('archive_audio', $url, $cached = FALSE);
|
||||
if ($response->code == 200) {
|
||||
$data['size'] = $response->headers['Content-Length'];
|
||||
$data['mime'] = $response->headers['Content-Type'];
|
||||
}
|
||||
|
||||
if ($data['size']) {
|
||||
$file = array();
|
||||
$file['filepath'] = $url;
|
||||
$file['filesize'] = $data['size'];
|
||||
$file['filemime'] = $data['mime'];
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emaudio_PROVIDER_embedded_link($audio_code)
|
||||
* returns a link to view the audio at the provider's site.
|
||||
* @param $audio_code
|
||||
* The string containing the audio item.
|
||||
* @return
|
||||
* A string containing the URL the audio item at the original provider's site.
|
||||
*/
|
||||
function emaudio_archive_audio_embedded_link($audio_code) {
|
||||
return 'http://www.archive.org/details/'. $audio_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook emaudio_archive_audio_audio().
|
||||
*
|
||||
* This actually displays the full/normal-sized audio we want, usually on the default page view.
|
||||
*
|
||||
* @param $embed
|
||||
* The audio code for the audio to embed.
|
||||
* @param $width
|
||||
* The width to display the audio.
|
||||
* @param $height
|
||||
* The height to display the audio.
|
||||
* @param $field
|
||||
* The field info from the requesting node.
|
||||
* @param $item
|
||||
* The actual content from the field.
|
||||
* @return
|
||||
* The html of the embedded audio.
|
||||
*/
|
||||
function emaudio_archive_audio_audio($embed = NULL, $width = 0, $height = 0, $field = NULL, $item, $node, $autoplay) {
|
||||
$output = theme('emaudio_archive_audio_flash', $embed, $width, $height, $field, $item, $node, $autoplay);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* The embedded flash displaying the archive audio.
|
||||
*/
|
||||
function theme_emaudio_archive_audio_flash($embed, $width, $height, $field, $item, $node, $autoplay) {
|
||||
$output = '';
|
||||
if ($item) {
|
||||
$flowplayerplaylist = _media_archive_flowplayer_playlist($item['data']['playlist']);
|
||||
$controlplaylist = (count($item['data']['playlist'])>1) ? "true" : "false";
|
||||
$clipautoplay = $autoplay ? 'true' : 'false';
|
||||
$output = <<<EOD
|
||||
<embed type="application/x-shockwave-flash" width="$width" height="$height" allowfullscreen="true"
|
||||
allowscriptaccess="always" src="http://www.archive.org/flow/flowplayer.commercial-3.0.5.swf" w3c="true"
|
||||
flashvars='config={
|
||||
"key":"#\$b6eb72a0f2f1e29f3d4",
|
||||
"playlist":[
|
||||
{$flowplayerplaylist}
|
||||
],
|
||||
"clip":{
|
||||
"autoPlay":{$clipautoplay}
|
||||
},
|
||||
"canvas":{
|
||||
"backgroundColor":"0x000000",
|
||||
"backgroundGradient":"none"
|
||||
},
|
||||
"plugins":{
|
||||
"audio":{
|
||||
"url":"http://www.archive.org/flow/flowplayer.audio-3.0.3-dev.swf"
|
||||
},
|
||||
"controls":{
|
||||
"playlist":{$controlplaylist},
|
||||
"fullscreen":false,
|
||||
"gloss":"high",
|
||||
"backgroundColor":"0x000000",
|
||||
"backgroundGradient":"medium",
|
||||
"sliderColor":"0x777777",
|
||||
"progressColor":"0x777777",
|
||||
"timeColor":"0xeeeeee",
|
||||
"durationColor":"0x01DAFF",
|
||||
"buttonColor":"0x333333",
|
||||
"buttonOverColor":"0x505050"
|
||||
}
|
||||
},
|
||||
"contextMenu":[
|
||||
{
|
||||
"Item {$item['value']} at archive.org":"function()"
|
||||
},
|
||||
"-",
|
||||
"Flowplayer 3.0.5"
|
||||
]
|
||||
}'>
|
||||
</embed>
|
||||
EOD;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_emfield_subtheme().
|
||||
*/
|
||||
function emaudio_archive_audio_emfield_subtheme() {
|
||||
return array(
|
||||
'emaudio_archive_audio_flash' => array(
|
||||
'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'field' => NULL, 'data' => NULL, 'node' => NULL, 'autoplay' => NULL),
|
||||
'file' => 'providers/emaudio/archive_audio.inc',
|
||||
'path' => drupal_get_path('module', 'media_archive'),
|
||||
)
|
||||
);
|
||||
}
|
407
sites/all/modules/media_archive/providers/emvideo/archive.inc
Normal file
407
sites/all/modules/media_archive/providers/emvideo/archive.inc
Normal file
@@ -0,0 +1,407 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This is an archive.org provider include file for Embedded Media Video.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the main URL for your provider.
|
||||
*/
|
||||
define('EMVIDEO_ARCHIVE_MAIN_URL', 'http://www.archive.org/');
|
||||
|
||||
/**
|
||||
* This is the URL to the API of your provider, if this exists.
|
||||
*/
|
||||
define('EMVIDEO_ARCHIVE_API_URL', 'http://www.google.com/search?q=archive.org+api');
|
||||
|
||||
/**
|
||||
* This defines the version of the content data array that we serialize
|
||||
* in emvideo_archive_data(). If we change the expected keys of that array,
|
||||
* we must increment this value, which will allow older content to be updated
|
||||
* to the new version automatically.
|
||||
*/
|
||||
define('EMVIDEO_ARCHIVE_DATA_VERSION', 2);
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_info
|
||||
* This returns information relevant to a specific 3rd party video provider.
|
||||
*
|
||||
* @return
|
||||
* A keyed array of strings requested by various admin and other forms.
|
||||
* 'provider' => The machine name of the provider. This must be the same as
|
||||
* the base name of this filename, before the .inc extension.
|
||||
* 'name' => The translated name of the provider.
|
||||
* 'url' => The url to the main page for the provider.
|
||||
* 'settings_description' => A description of the provider that will be
|
||||
* posted in the admin settings form.
|
||||
* 'supported_features' => An array of rows describing the state of certain
|
||||
* supported features by the provider. These will be rendered in a table,
|
||||
* with the columns being 'Feature', 'Supported', 'Notes'. In general,
|
||||
* the 'Feature' column will give the name of the feature, 'Supported'
|
||||
* will be Yes or No, and 'Notes' will give an optional description or
|
||||
* caveats to the feature.
|
||||
*/
|
||||
function emvideo_archive_info() {
|
||||
$features = array(
|
||||
array(t('Autoplay'), t('Yes'), ''),
|
||||
array(t('RSS Attachment'), t('Yes'), ''),
|
||||
array(t('Thumbnails'), t('Yes'), t('')),
|
||||
array(t('Full screen mode'), t('Yes'), t('You may customize the player to enable or disable full screen playback. Full screen mode is enabled by default.')),
|
||||
);
|
||||
return array(
|
||||
'provider' => 'archive',
|
||||
'name' => t('archive.org'),
|
||||
'url' => EMVIDEO_ARCHIVE_MAIN_URL,
|
||||
'settings_description' => t('These settings specifically affect videos displayed from !archive. You can also read more about its !api.', array('!archive' => l(t('Archive.com'), EMVIDEO_ARCHIVE_MAIN_URL), '!api' => l(t("developer's API"), EMVIDEO_ARCHIVE_API_URL))),
|
||||
'supported_features' => $features,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_settings
|
||||
* This should return a subform to be added to the emvideo_settings() admin
|
||||
* settings page.
|
||||
*
|
||||
* Note that a form field set will already be provided at $form['archive'],
|
||||
* so if you want specific provider settings within that field set, you should
|
||||
* add the elements to that form array element.
|
||||
*/
|
||||
function emvideo_archive_settings() {
|
||||
// We'll add a field set of player options here. You may add other options
|
||||
// to this element, or remove the field set entirely if there are no
|
||||
// user-configurable options allowed by the archive provider.
|
||||
/* $form['archive']['player_options'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Embedded video player options'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
// This is an option to set the video to full screen. You should remove this
|
||||
// option if it is not provided by the archive provider.
|
||||
$form['archive']['player_options']['emvideo_archive_full_screen'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Allow fullscreen'),
|
||||
'#default_value' => variable_get('emvideo_archive_full_screen', 1),
|
||||
'#description' => t('Allow users to view video using the entire computer screen.'),
|
||||
);
|
||||
|
||||
return $form;*/
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_extract
|
||||
*
|
||||
* This is called to extract the video code from a pasted URL or embed code.
|
||||
*
|
||||
* We'll be passed a URL or the embed code from a video when an editor pastes
|
||||
* that in the field's textfield. We'll need to either pass back an array of
|
||||
* regex expressions to match, or do the matching ourselves and return the
|
||||
* resulting video code.
|
||||
*
|
||||
* @param $parse
|
||||
* An optional string with the pasted URL or embed code.
|
||||
* @return
|
||||
* Either an array of regex expressions to be tested, or a string with the
|
||||
* video code to be used. If the hook tests the code itself, it should
|
||||
* return either the string of the video code (if matched), or an empty
|
||||
* array. Otherwise, the calling function will handle testing the embed code
|
||||
* against each regex string in the returned array.
|
||||
*/
|
||||
function emvideo_archive_extract($parse = '') {
|
||||
// Here we assume that a URL will be passed in the form of
|
||||
// http://www.archive.org/video/text-video-title
|
||||
// or embed code in the form of <object value="http://www.archive.org/embed...".
|
||||
|
||||
// We'll simply return an array of regular expressions for Embedded Media
|
||||
// Field to handle for us.
|
||||
return array(
|
||||
//In the URL the archive.org item id will appear after "details/" in the URL
|
||||
'@archive\.org\/details\/([^\"\&]+)@i',
|
||||
|
||||
// Now we test for embedded video code, which is similar in this case to
|
||||
// the above expression, except the item id will appear after "download/"
|
||||
'@archive\.org/download/([^/]+)@i',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement hook emvideo_PROVIDER_data_version().
|
||||
*/
|
||||
function emvideo_archive_data_version() {
|
||||
return EMVIDEO_ARCHIVE_DATA_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_data
|
||||
*
|
||||
* Provides an array to be serialised and made available with $item elsewhere.
|
||||
*
|
||||
* This data can be used to store any extraneous information available
|
||||
* specifically to the archive provider.
|
||||
*/
|
||||
function emvideo_archive_data($field, $item, $error_field = '') {
|
||||
|
||||
// Initialize the data array.
|
||||
$data = array();
|
||||
|
||||
// Create some version control. Thus if we make changes to the data array
|
||||
// down the road, we can respect older content. If allowed by Embedded Media
|
||||
// Field, any older content will automatically update this array as needed.
|
||||
// In any case, you should account for the version if you increment it.
|
||||
$data['emvideo_archive_version'] = $data['emvideo_data_version'] = EMVIDEO_ARCHIVE_DATA_VERSION;
|
||||
|
||||
// Construct a base item url
|
||||
$item_url = "http://www.archive.org/details/". $item['value'];
|
||||
$download_url = "http://www.archive.org/download/". $item['value'];
|
||||
|
||||
// We will leverage the JSON archive.org api to get details about this item
|
||||
// See http://www.archive.org/help/json.php
|
||||
$xml_meta_url = $item_url .'&output=json';
|
||||
$xml_meta = media_archive_request_xml('archive', $xml_meta_url, array(), TRUE, TRUE, $item['value'] .'_meta', FALSE, TRUE);
|
||||
if ($xml_meta['stat'] == 'error' || empty($xml_meta)) {
|
||||
drupal_set_message('This item\'s details cannot be retrieved. The video can not be displayed.');
|
||||
return $data;
|
||||
}
|
||||
else {
|
||||
$data['details'] = $xml_meta;
|
||||
$server_url = $data['details']['server'] . $data['details']['dir'];
|
||||
}
|
||||
|
||||
$item_files = $data['details']['files'];
|
||||
|
||||
if (!$item_files) {
|
||||
form_set_error($error_field, 'The list of files for the item at archive.org could not be retrieved. The video can not be displayed.');
|
||||
return $data;
|
||||
}
|
||||
|
||||
//Putting the $key (which is actually the file name) as an element of the
|
||||
//array too for convenience later.
|
||||
foreach ($item_files as $key => $value) {
|
||||
$item_files[$key]['name'] = $key;
|
||||
}
|
||||
|
||||
//Get only .mp4 files
|
||||
$files_play = array_filter($item_files, "_archive_video_toplay");
|
||||
|
||||
//If there is no playlist then fail
|
||||
if (is_null($files_play)) {
|
||||
form_set_error($error_field, 'This archive.org item does not appear to have files to play.');
|
||||
return $data;
|
||||
}
|
||||
|
||||
//Create a playlist suitable for feeding to player
|
||||
foreach ($files_play as $file => $file_data) {
|
||||
$data['playlist'][] = $download_url . $file;
|
||||
}
|
||||
|
||||
// Add the thumbnail data.
|
||||
$data['thumbnail'] = 'http://www.archive.org/download/'. $item['value'] .'/format=Thumbnail?.jpg';
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a 512Kb MPEG4 file?
|
||||
*/
|
||||
function _archive_video_toplay($file) {
|
||||
if ($file['format'] == "512Kb MPEG4") {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_duration($item)
|
||||
* Returns the duration of the video in seconds.
|
||||
* @param $item
|
||||
* The video item itself, which needs the $data array.
|
||||
* @return
|
||||
* The duration of the video in seconds.
|
||||
*/
|
||||
function emvideo_archive_duration($item) {
|
||||
if (!isset($item['data']['emvideo_archive_version'])) {
|
||||
$item['data'] = emvideo_archive_data(NULL, $item);
|
||||
}
|
||||
return isset($item['data']['metadata']['RUNTIME'][0]) ? emvideo_convert_to_seconds($item['data']['metadata']['RUNTIME'][0]) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_rss
|
||||
*
|
||||
* This attaches a file to an RSS feed.
|
||||
*/
|
||||
function emvideo_archive_rss($item, $teaser = NULL) {
|
||||
if ($item['value']) {
|
||||
$file['thumbnail']['filepath'] = $item['data']['thumbnail'];
|
||||
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_embedded_link($video_code)
|
||||
* returns a link to view the video at the provider's site.
|
||||
* @param $video_code
|
||||
* The string containing the video to watch.
|
||||
* @return
|
||||
* A string containing the URL to view the video at the original provider's site.
|
||||
*/
|
||||
function emvideo_archive_embedded_link($video_code) {
|
||||
return 'http://www.archive.org/details/'. $video_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* The embedded flash displaying the archive video.
|
||||
*/
|
||||
function theme_emvideo_archive_flash($item, $width, $height, $autoplay) {
|
||||
$output = '';
|
||||
if ($item['embed']) {
|
||||
$flowplayerplaylist = _media_archive_flowplayer_playlist($item['data']['playlist']);
|
||||
$controlplaylist = (count($item['data']['playlist'])>1) ? "true" : "false";
|
||||
$clipautoplay = $autoplay ? 'true' : 'false';
|
||||
$output = <<<EOD
|
||||
<embed type="application/x-shockwave-flash" width="$width" height="$height" allowfullscreen="true"
|
||||
allowscriptaccess="always" src="http://www.archive.org/flow/flowplayer.commercial-3.0.5.swf"
|
||||
w3c="true" flashvars='config={
|
||||
"key":"#\$b6eb72a0f2f1e29f3d4",
|
||||
"playlist":[
|
||||
{
|
||||
"url":"{$item['data']['thumbnail']}",
|
||||
"autoPlay":true,
|
||||
"scaling":"fit"
|
||||
},
|
||||
{$flowplayerplaylist}
|
||||
],
|
||||
"clip":{
|
||||
"autoPlay":false,
|
||||
"accelerated":true,
|
||||
"scaling":"fit"
|
||||
},
|
||||
"canvas":{
|
||||
"backgroundColor":"0x000000",
|
||||
"backgroundGradient":"none"
|
||||
},
|
||||
"plugins":{
|
||||
"audio":{
|
||||
"url":"http://www.archive.org/flow/flowplayer.audio-3.0.3-dev.swf"
|
||||
},
|
||||
"controls":{
|
||||
"playlist":{$controlplaylist},
|
||||
"fullscreen":true,
|
||||
"gloss":"high",
|
||||
"backgroundColor":"0x000000",
|
||||
"backgroundGradient":"medium",
|
||||
"sliderColor":"0x777777",
|
||||
"progressColor":"0x777777",
|
||||
"timeColor":"0xeeeeee",
|
||||
"durationColor":"0x01DAFF",
|
||||
"buttonColor":"0x333333",
|
||||
"buttonOverColor":"0x505050"
|
||||
}
|
||||
},
|
||||
"contextMenu":[
|
||||
{
|
||||
"{$item['value']}":"function()"
|
||||
},
|
||||
"-",
|
||||
"Flowplayer 3.0.5"
|
||||
]
|
||||
}'> </embed>
|
||||
EOD;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_thumbnail
|
||||
* Returns the external url for a thumbnail of a specific video.
|
||||
* @param $field
|
||||
* The field of the requesting node.
|
||||
* @param $item
|
||||
* The actual content of the field from the requesting node.
|
||||
* @return
|
||||
* A URL pointing to the thumbnail.
|
||||
*/
|
||||
function emvideo_archive_thumbnail($field, $item, $formatter, $node, $width, $height) {
|
||||
// In this demonstration, we previously retrieved a thumbnail using oEmbed
|
||||
// during the data hook.
|
||||
return $item['data']['thumbnail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_video
|
||||
* This actually displays the full/normal-sized video we want, usually on the
|
||||
* default page view.
|
||||
* @param $embed
|
||||
* The video code for the video to embed.
|
||||
* @param $width
|
||||
* The width to display the video.
|
||||
* @param $height
|
||||
* The height to display the video.
|
||||
* @param $field
|
||||
* The field info from the requesting node.
|
||||
* @param $item
|
||||
* The actual content from the field.
|
||||
* @return
|
||||
* The html of the embedded video.
|
||||
*/
|
||||
function emvideo_archive_video($embed, $width, $height, $field, $item, $node, $autoplay) {
|
||||
$output = theme('emvideo_archive_flash', $item, $width, $height, $autoplay);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* hook emvideo_PROVIDER_video
|
||||
*
|
||||
* This actually displays the preview-sized video we want, commonly for the
|
||||
* teaser.
|
||||
* @param $embed
|
||||
* The video code for the video to embed.
|
||||
* @param $width
|
||||
* The width to display the video.
|
||||
* @param $height
|
||||
* The height to display the video.
|
||||
* @param $field
|
||||
* The field info from the requesting node.
|
||||
* @param $item
|
||||
* The actual content from the field.
|
||||
* @return
|
||||
* The html of the embedded video.
|
||||
*/
|
||||
function emvideo_archive_preview($embed, $width, $height, $field, $item, $node, $autoplay) {
|
||||
$output = theme('emvideo_archive_flash', $item, $width, $height, $autoplay);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_emfield_subtheme().
|
||||
* This returns any theme functions defined by this provider.
|
||||
*/
|
||||
function emvideo_archive_emfield_subtheme() {
|
||||
$themes = array(
|
||||
'emvideo_archive_flash' => array(
|
||||
'arguments' => array('item' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
|
||||
'file' => 'providers/archive.inc',
|
||||
// If you don't provide a 'path' value, then it will default to
|
||||
// the emvideo.module path. Obviously, replace 'emarchive' with
|
||||
// the actual name of your custom module.
|
||||
//'path' => drupal_get_path('module', 'emarchive'),
|
||||
)
|
||||
);
|
||||
return $themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement hook_emvideo_PROVIDER_content_generate().
|
||||
*/
|
||||
function emvideo_archive_content_generate() {
|
||||
return array(
|
||||
'http://www.archive.org/details/DrupalconDc2009-DrupalMultimedia',
|
||||
'http://www.archive.org/details/DrupalconBoston2008-DrupalMultimedia',
|
||||
'http://www.archive.org/details/drupal_song_dcamp_pune_09',
|
||||
'http://www.archive.org/details/Drupal.Peru_DrupalSong20090718',
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user