Twitter Cardsを使う

記事を投稿した際にその記事のURLリンクとハッシュタグを挿入してTwitterへツイートするために、「Twitter」モジュールを利用しました。
このとき挿入されるURLリンクは短縮形URLが使用されるため、リンク先がどういったサイトなのかが不明でタイトルとは全く異なるサイトへとばしフィッシング詐欺などに悪用されることもありました。

今回は、記事の内容、画像や動画などのコンテンツをツイートに添付する「Twitter Cards」を紹介します。

Twitter Cardsで添付されたコンテンツは、どのデバイスのTwitterクライアントからも同じように表示されるような仕組みになっています。
そのため、URLリンク(短縮リンク)ボタンだけが添付されたツイートとは異なり、リンク先へ訪問しなくても添付されたコンテンツを閲覧できます。

Twitter Cardsでは、7種類のカードが用意されています。
ここでは、Playerカードを使って動画を添付する方法について説明します。
 

手順の概略

Twitter Cardsに添付したいコンテンツのヘッダー部にメタタグの追加が必要になります。
必要なメタタグは添付するカードの種類で異なります。
 

Palyerカードに関係するメタダグ

ツイートにPlayerカードを添付するには以下の表にあるメタタグの記述が必要になります。

メタタグ 説明
twitter:card player
twitter:site @username
Twitterのユーザ名
カードの下に表示される
twitter:site:id @username_
TwitterのユーザID
twitter:creator @username
コンテンツの作成者
twitter:creator:id @username
コンテンツ作成者のTittwerのユーザID
twitter:description
(og:description)
コンテンツの説明(200文字以内)
twitter:title
(og:title)
コンテンツのタイトル(70文字以内)
twitter:image:src
(og:image)
カードで使用する画像のURL(1MB未満)
twitter:image:width
(og:image:width)
画像の幅(単位:ピクセル)
twitter:image:height
(og:image:height)
画像の高さ(単位:ピクセル)
twitter:player iFrame Player用のセキュアURL
(https://~)
twitter:player:width iFrameの幅(単位:ピクセル)
twitter:player:height iFrameの高さ(単位:ピクセル)
twitter:player:stream 直接再生する場合のストリーミングファイルのURL
twitter:player:stream:content_type ビデオおよび音楽ファイルのMIMEタイプ
RFC 6381参照
※()内のタグは、Open GrapheのものでFacebookなどで使われます。一部、Twitter Cardsでも利用できますので重複して記述する必要がなくなります。
  の箇所は必須です。
※twitter:player:stream:content_typeに設定する値は、Twitter Cardsではデスクトップ、iPhone、Androidなどすべてのデバイスで再生できることが条件になりますので、ビデオコンテンツの場合は消去法でvideo/mp4になると思います。
※twitter:player:streamが使われている場合は、直接ストリーミング再生をしますので、twitter:player:stream:content_typeが必須になります。
※twitter:player:streamが使われていない場合は、twitter:playerで指定したiFrame Playerで再生をします。
※詳細は、「プラットフォームによるPlayerカードの動作の違い」を参照してください。


このメタタグの追加がメインの作業になります。
このあとは、申請して承認されれば実際に使用できるようになります。
 

手順の詳細

以下、このDrupalサイトで実施した手順になります。
 

今回使用したDrupalモジュール

他にもいろいろなモジュールが関係していますが、ここでは直接関係するモジュールのみピックアップしています。

Views 7.x-3.8 Drupal 7.xではコアに1部吸収されていますのでそれ以外の機能のためです。
なお、Drupal7のViewsは3.xです。
Views data export 7.x-3.0-beta8 Viewsの結果をTXT、CSV、DOC、XLS、XML形式に出力するためのモジュールです。
RobotsTxt 7.x-1.3 robots.txtを編集するにはサーバにリモートログインしエディタを起動しなければなりませんが、このモジュールを使えばDrupalの管理画面から編集が可能になります。
※サーバ上のローカルディレクトリにファイルは存在しません。
Metatag 7.x-1.4 meta tagを管理するためのモジュールです。
サブモジュールにDublin Core、Open Graph、Twittercard、Facebook、Google+用などがあります。
Twitter 7.x-5.8 Twitterとの連携用のモジュールです。
OAuth 7.x-3.2 Twitterとの連携時の認証に使用するモジュールです。
Image URL Formatter 7.x-1.4 通常は画像フィールドの場合、画像スタイルの選択しかありませんが、URLを選択することができるようになります。
iFrame Playerで使用するポスター画像のURL抽出が容易になりました。

 

iFrame Playerの作成(まだFixしていません)

このiFrame Playerはデスクトップクライアント(ブラウザーでtwitter.comにアクセス)で使われます。
一方、mobile.twitter.comにアクセスするクライアント(iPhoneやAndroidのブラウザ)の場合は、まず、「twitter:player:stream」の指定があればそのファイルを直接ストリーミング再生するよう、「twitter:image」の画像に再生ボタンの画像を貼り付け、ストリームデータを直接再生します。
指定がない場合はiFrame Playerが使用されるようです。
iFrame Playerがあればすべてに対応できるといえます。

そのため、iFrame Playerはすべてのクライアントで再生可能でなければなりません。
しかし、投稿した記事の一部に動画を埋め込んだ場合、この記事のURLを「twitter:player」に指定してしまうと、サイトのページ全体が表示されるだけです。
そのため、別途、iFrame Playerを作成します。

iFrame Playerを別途作成するために「Views」と「Views data export」モジュールを使用します。
この「Views data export」モジュールは「Views」の結果を特定のファイル形式で出力するためのものです。
ただし、Drupal 6.xで作成したplaylistの時とは異なり、Drupal 7.xでは通常、ダウンロードファイルとして作成されます。
これをファイルとして作成しようとしても出力ファイル形式によって動作が異なり、どの形式であってもローカルディスク上に作成されるわけではないようです。

現時点では、とりあえずTXT形式で生成まではできるようになりましたが、生成した出力結果がPREタグで囲まれてしまうため、せっかく記述したHTMLソースがplaintextとして表示されてiFrame Playerとして動作してくれません。
PREタグが挿入される

Viewsの出力がPREタグ(黄色箇所)で囲まれているため、表示するブラウザーが自動的にヘッダー部を追加してしまっています。(図はFireFoxの例)

ファイル出力がPREタグで囲まれないようにするまでは、iFrame Playerを手作業でコピー&ペーストするかダウンロードファイルとして作成してアップロードして対応するしかありません。
動画を作成する頻度が以前ほどありませんので、今はこの方法でもなんとかなっています。

以下、iFrame Playerの生成方法です。
 

Viewsの設定

Viewsの名前は「TwitterCard」(システム名twittercard)で作成しました。
構成はページとデータエクスポートです。データエクスポートはページに添付してあります。

以下は作成したViewsのエクスポートですので、インポートしてサイトに合わせて修正すれば使用することも可能です。

$view = new view();
$view->name = 'twittercard';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'TwitterCard';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'TwitterCard';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['use_more_text'] = '続き...';
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['exposed_form']['options']['submit_button'] = '適用';
$handler->display->display_options['exposed_form']['options']['reset_button_label'] = 'リセット';
$handler->display->display_options['exposed_form']['options']['exposed_sorts_label'] = '並び替え基準';
$handler->display->display_options['exposed_form']['options']['sort_asc_label'] = '昇順';
$handler->display->display_options['exposed_form']['options']['sort_desc_label'] = '降順';
$handler->display->display_options['pager']['type'] = 'some';
$handler->display->display_options['pager']['options']['items_per_page'] = '1';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* フィールド: コンテンツ: video_file */
$handler->display->display_options['fields']['field_video_file']['id'] = 'field_video_file';
$handler->display->display_options['fields']['field_video_file']['table'] = 'field_data_field_video_file';
$handler->display->display_options['fields']['field_video_file']['field'] = 'field_video_file';
$handler->display->display_options['fields']['field_video_file']['label'] = '';
$handler->display->display_options['fields']['field_video_file']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['field_video_file']['element_default_classes'] = FALSE;
$handler->display->display_options['fields']['field_video_file']['click_sort_column'] = 'fid';
$handler->display->display_options['fields']['field_video_file']['type'] = 'file_url_plain';
/* フィールド: コンテンツ: image_file */
$handler->display->display_options['fields']['field_image_file']['id'] = 'field_image_file';
$handler->display->display_options['fields']['field_image_file']['table'] = 'field_data_field_image_file';
$handler->display->display_options['fields']['field_image_file']['field'] = 'field_image_file';
$handler->display->display_options['fields']['field_image_file']['label'] = '';
$handler->display->display_options['fields']['field_image_file']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['field_image_file']['element_default_classes'] = FALSE;
$handler->display->display_options['fields']['field_image_file']['click_sort_column'] = 'fid';
$handler->display->display_options['fields']['field_image_file']['type'] = 'image_url';
$handler->display->display_options['fields']['field_image_file']['settings'] = array(
  'url_type' => '0',
  'image_style' => '',
  'image_link' => '',
);
/* Contextual filter: コンテンツ: ノードID */
$handler->display->display_options['arguments']['nid']['id'] = 'nid';
$handler->display->display_options['arguments']['nid']['table'] = 'node';
$handler->display->display_options['arguments']['nid']['field'] = 'nid';
$handler->display->display_options['arguments']['nid']['default_action'] = 'default';
$handler->display->display_options['arguments']['nid']['exception']['title'] = 'すべて';
$handler->display->display_options['arguments']['nid']['default_argument_type'] = 'node';
$handler->display->display_options['arguments']['nid']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['nid']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['nid']['summary_options']['items_per_page'] = '25';
/* Filter criterion: コンテンツ: 掲載 */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: コンテンツ: video_file (field_video_file:fid) */
$handler->display->display_options['filters']['field_video_file_fid']['id'] = 'field_video_file_fid';
$handler->display->display_options['filters']['field_video_file_fid']['table'] = 'field_data_field_video_file';
$handler->display->display_options['filters']['field_video_file_fid']['field'] = 'field_video_file_fid';
$handler->display->display_options['filters']['field_video_file_fid']['operator'] = 'not empty';

/* Display: データエクスポート */
$handler = $view->new_display('views_data_export', 'データエクスポート', 'views_data_export_1');
$handler->display->display_options['pager']['type'] = 'none';
$handler->display->display_options['pager']['options']['offset'] = '0';
$handler->display->display_options['style_plugin'] = 'views_data_export_txt';
$handler->display->display_options['style_options']['provide_file'] = 0;
$handler->display->display_options['style_options']['parent_sort'] = 0;
$handler->display->display_options['path'] = 'media/%/iframe.html';
$handler->display->display_options['displays'] = array(
  'page_1' => 'page_1',
  'default' => 0,
  'block' => 0,
);
$handler->display->display_options['segment_size'] = '100';

/* Display: ページ */
$handler = $view->new_display('page', 'ページ', 'page_1');
$handler->display->display_options['path'] = 'twittercard/%';
$translatables['twittercard'] = array(
  t('Master'),
  t('TwitterCard'),
  t('続き...'),
  t('適用'),
  t('リセット'),
  t('並び替え基準'),
  t('昇順'),
  t('降順'),
  t('すべて'),
  t('データエクスポート'),
  t('ページ'),
);

 

解説

ページヘのアクセスは、「/twittercard/nid」(nidはノード番号)で行います。
ノードIDを引数に一致したコンテンツのフィールド名video_fileとimage_fileのそれぞれのURLが表示されます。
その下にある「TXT」のボタンをクリックすれば、データエクスポートの結果が画面に出力されます。(本当はiFrame Playerが表示されるはずでしたが・・・)
iFrame Playerのパスは、「media/nid/iframe.html」(nidはノード番号)になります。
※当サイトのパブリックファイルシステムパスは標準のfilesではなくmediaに変更してあります。
 

Viewsテンプレートの作成

そのままViewsの結果をただTXT形式で出力してもフィールドに指定した値が表示されているだけにすぎません。
以下のようにviewsテンプレートを作成して、iFrame Playerにふさわしい出力に整形します。
 

<?php
  $id=explode("\n",$rows['body']);
  $movie=$id[2];
  $thumb=$id[5];
?>
<!DOCTYPE html>
  <html>
    <body>
      <style type="text/css">
        video {
          width:100%;
          max-width:600px;
          height:auto;
        }
      </style>
      <video
        controls="controls"
        width=100%
        poster="<?php print $thumb ?>"
        type="video/mp4">
        src="<?php print $movie ?>"
      >
      </video>
    </body>
  </html>

Twitter Cardsスターターキットを参考に作成しました。
ポスター画像とコントロールボタンを表示するように追加してあります。
※ビデオソースは1つを想定して記述してありますが、複数指定する場合は、以下のように記述することも可能です。

<video controls width=100% poster="sample.png">
 <source src='sample.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
 <source src="sample.webm" type='video/webm; codecs="vp8, vorbis"' >
 <source src='sample.ogv' type='video/ogg; codecs="theora, vorbis"'>
</Video>

この場合、上から順番に再生可能なビデオファイルが再生されます。
ただし、この場合、Palyerカードの条件を満たさないと思います。
 

Viewsテンプレートファイルの再スキャン

所定の場所にテンプレートを作成しただけではそのファイルを使用しません。
Viewsで作成したテンプレートファイルを使用するように「テンプレートファイルを再スキャン」を実行し、作成したテンプレートファイルが選択されていることを確認します。

現在使用されているテンプレートファイルを表示するには、画面右端にある「高度」の中の一番下にある「テーマ:情報」をクリックします。
テーマ:情報

ポップアップ画面が表示され、それぞれ現在使われているテンプレートファイルが太文字で表示されます。
画面一番下にある「テンプレートファイルを再スキャン」ボタンをクリックすれば、先ほど作成したテンプレートファイルが太文字に変わります。

テンプレートファイルを再スキャン

※うまく変わらない場合は、テンプレートファイルを配置した場所が間違っているかファイル名が間違っています。
最後に「OK」をクリックして、編集中のViewsを保存すれば完了です。

さきほどのポップアップ画面でViewsテンプレートファイルを作成する場合にどのファイル名で作成すればよいかを確認することもできます。
 

iFrame Playerの確認

先ほどのiframe Playerを設定したURLに直接アクセスして正しく表示されるかを確認します。
ここで正しく表示されなければ、先の「Card Validator」でも同じ結果になってしまいます。

本来は「/media/nid/iframe.html」にアクセスするだけでよいのですが、前述したようにまだ未完成であるため、サーバ上のディレクトリ「media/nid/iframe.html」にファイルを作成します。
ファイルに記述する内容は、「/media/nid/iframe.html」にアクセスした時に表示された内容をコピー&ペーストするだけです。(暫定策)

Viewsで作成したページにアクセスした場合(例:nid=7609)
https://phoenixknight.jp/twittercard/7609


「TXT」ボタンをクリックした場合
iFrame Playerの記述内容
表示された内容をサーバ上の「/media/7609/iframe.html」ファイル内にコピー&ペーストします。(暫定策)
※ファイルは存在していないはずなので作成してください。

iFrame Playerを確認します。
ファイルを保存したあと、再度、「/media/nid/iframe.html」にアクセスして動画が表示され再生できれば正常です。
※表示されること、動画が再生されることを確認してください。
https://phoenixknight.jp/media/7609/iframe.html
※うまく再生されない場合、VIDEOタグに記述したパラメータは「半角スペース」で区切られています。
改行とTABだけで記述するとパラメータがつながってしまい意味のない文字列になってしましますので注意してください。
※iFrame Playerを表示した際にブラウザーで「安全でないコンテンツのブロック」の状態だとNGです。
ブラウザー毎に表示はことなりますが、FireFoxの場合は「http://」の前に!マークとさらにその前に盾マークが表示されます。
Chromeの場合は、https://の前の鍵マークが黄色でアドレス欄のうしろに盾マークが表示されるかと思います。
IEの場合は、画面下にポップアップメッセージ(セキュリティで保護されているコンテンツのみが表示されています)が表示されるかと思います。
※iframe PlayerのURLおよび内部で使用しているURLはすべてセキュアパスでなければなりませんので、「http://」から始まるURLパス表記はNGになります。
※ブラウザーによってはPlayerのパーツが異なります。FireFoxではフルスクリーンボタンが表示されます。
 

メタタグの追加

前述したように、Twitter Cardsを使うには、まず、自サイトの記事などにTwitter Cardsで利用されるメタタグを追加する必要があります。
これを簡単に行うためDrupalの寄贈モジュールで提供されている「Meta tag」モジュールを利用します。
このモジュールは、SEO対策などでも紹介されていますが、うまく動作しないなどのバグがあったりで他のモジュールを使用している方もいると思います。
私のサイトでは特に問題がなかったので、このモジュールを利用しています。
 

「Metatag:Twitter Cards」モジュールの有効化

Twitter Cards用のメタタグを追加するには、「Meta tag」モジュールのサブモジュールである「Metatag:Twitter Cards」を有効にします。
「/admin/module」のページを表示して有効にするだけです。

サブモジュールの有効化
 

メタタグの設定

「/admin/config/search/metatags」のページを表示します。

編集

「Add a Metatag default」をクリックしてコンテンツタイプ(movies)専用の設定を作成し編集しています。

Open Graphをできるだけ利用して不足している項目だけTwitter Cardで設定するようにしました。
 

OPENGRAPHで設定した項目

※[]はTokenです。

項目 設定値
Page URL [current-page:url:absolute]
Content title [node:title]
Image URL [node:field_blog_image:body_fixed]
Secure image URL [node:field_blog_image:body_fixed]
Image width 320
Image height 240

 

TWITTER CARDで設定した項目

※[]はTokenです。

項目 設定値
Twitter Card Type Media player
説明 [node:summary]
Media player URL https://phoenixknight.jp/media/[node:nid]/iframe.html
Media player width 320
media player height 240

※画像の表示サイズ(幅、高さ)とPlayerの表示サイズ(幅、高さ)は必ず同じになるようにしてください。
※オリジナルの画像サイズは120x120以上でファイルサイズは1MB未満の制限があったと思います。
 

「twitter:site」の追加(Optional?)

「Metatag:Twitter Cards」のサブモジュールでは対応していないのが「twitter:site」です。
必須にはなってないのですが、これを設定してない場合、下図のように赤色で囲んだ箇所のリンクボタンが正しく表示されません。

Twitterサイトへのリンク切れ
ブラウザーがFireFoxの場合はリンク切れが見えませんが、IEなど他のブラウザーではXや?マークが表示されます。
FireFoxの場合ならFirebugブラグインをインストールしてHTMLソースを見ると確認できます。

この影響でのちの承認が通らないのかどうかは不明ですが、「twitter:site」が設定してあれば正しく表示されるようになります。

これの対処のために、テーマ・テンプレートファイル(/sites/all/themes/pegasus/template.php)の2箇所にそれぞれ以下の内容を追加します。
※テーマ名pegasus、コンテンツタイプmoviesの例です。

function pegasus_preprocess_node(&$vars) {
  $node = $vars['node'];
  if ($node->type == 'movies') {
    $tag = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'name' => 'twitter:site', // Card property to be implemented
        'content' => '@phoenixknight_', // the value of the Card property
      ),
    );
    drupal_add_html_head($tag, 'pegasus_twitter:site');
  }
}

 

 function pegasus_html_head_alter(&$head_elements) {
   foreach ($head_elements as $key => $element) {
      switch ($key) {
        case 'metatag_twitter:site':
          if ($node = menu_get_object()) {
            if ($node->type == 'movies') {
              unset($head_elements['metatag_twitter:site']);
            }
          }
        break;
      }
    }
}

※すでに、「function pegasus_preprocess_node(&$vars)」や「function pegasus_html_head_alter(&$head_elements)」の記述がある場合はその中に追記しないと重複エラーになります。
 

参照先のフィールドに複数の登録がある場合の対応(Optional)

フィールドの値が複数ある場合に、上記のTokenを利用すると当該フイールドのすべての値が出力されてしまいます。
しかし、og:imageやtwitter:imageでは1つのファイルを想定しているために複数の値が代入されるとうまく表示することができません。
これに対処するため、画像フィールドなどのように複数の値があるケースを想定して、最初の1つの要素だけを出力するように修正します。
※フィールドの設定で値の数を1(初期値)にしてある場合は問題ありません。

先ほどと同じくテーマ・テンプレートファイル(/sites/all/themes/pegasus/template.php)を編集します。
※テーマ名pegasusの例です。

 function pegasus_html_head_alter(&$head_elements) {
    if(isset($head_elements['metatag_og:image'])){
      $images = $head_elements['metatag_og:image']['#value'];
        if(strpos($images, ", ") != FALSE){
            $head_elements['metatag_og:image']['#value'] = substr($images, 0, strpos($images, ", "));
        }
    }
    if(isset($head_elements['metatag_twitter:image'])){
      $images = $head_elements['metatag_twitter:image']['#value'];
      if(strpos($images, ", ") != FALSE){
            $head_elements['metatag_twitter:image']['#value'] = substr($images, 0, strpos($images, ", "));
      }
    }
 }
 

strpos関数で「, 」(半角カンマ+半角スペース)の位置を調べ、substr関数で文字列の先頭からカンマまでの文字列を抽出しているだけのプログラムです。
 

twitterbot対応

Twitter Botが巡回できるようにrobots.txtを編集します。
いろいろと書き方はありますが、ここでは簡単に以下のようにTwitterbotのみ無制限で許可にしてあります。
 

User-agent: Twitterbot
Disallow:

 

申請前チェック

申請前に「Card Validator」で実際にカードが表示されるかのチェックを行い承認までの工程がスムーズに完了できるようにします。
チェックは、できるだけ多くのプラットフォームで実施したほうが承認までスムーズに完了すると思います。
iPhoneは所持していないのでデスクトップとAndroid端末(スマートフォン)で実施しました。


Card Validator」にアクセスします。
Card URLにサイト内のコンテンツのURLを入力し、「Preview card」ボタンをクリックします。
Card Validator

この図は、承認前の申請中の状態です。
※Card URLにnode/7609のURLパスを入力するとエラーになりました。
URLエイリアスの影響が考えられますので、対象のページを表示した時にブラウザーのアドレス欄に表示されているURLをコピー&ペーストするほうが確実かと思います。

表示がうまくいってもそれだけでは承認はOKにはなりません。
Twitterルールなどにも目を通して理解しておいてください。
 

利用申請と結果

申請は「Card Validator」の画面から行います。
エラー(ビンク色のメッセージ)がなく審査中(黄色でpending approvalのメッセージ)でなければ「」ボタンが表示さますので、そちらから必要事項を記入して送信すれば4・5日で審査結果のメールが届きます。
Witelistに登録されれば利用開始ですので、承認されればCard Validatorの出力メッセージがすべてグリーンで表示されるようになるはずです。
 

iFrame Playerが生成されるタイミング

例えばImagecacheの加工後の画像がいつ作成されるのか?という疑問と同じでDrupal 6.xとDrupal 7.xとでタイミングは異ると思います。
このサイトの例でいうと、本文で使用している画像はimagecacheを使用したbody_fixedスタイルで貼り付けていますが、貼り付け操作と同時に画像が生成されているので記事を保存直後も画像が表示されます。
しかし、フロントページに使用しているティザー表示の画像は同じくimagecacheで生成していますが記事を保存したタイミングでは生成されていません。

この対処のため、Drupal 7.xではImagecacheに使われているすべての画像を表示するViewsを作成して、プレビューする作業をしています。

今回、これと同じようなことになるのではと思い、わざわざページにiFrame Playerを作成するデーターエクスポートを添付しています。
確実に生成されるようにページにアクセスして「TXT」ボタンをクリックして表示させれば良いと思いますが、問題は記事を初めて保存した際に記事の保存と同時にTwitterへツィートを送信してしまうと、この時点ではiFrame Playerが生成されていない可能性があります。

また、本文に貼り付けるのと同じ画像スタイルを使用した場合、貼り付け操作と同時に生成され保存と同時に所定の場所に保存されているので問題はないと思いますが、Twitter Cards専用の画像スタイルを使っている場合に問題が発生すると思います。

TwitterCardsで使用している画像やiFrame Playerが確実に生成されていることを確認したのち、ツィートしないといけません。

①最初にコンテンツを保存するときはTwitterにツィートせずに保存
②Viewsで画像およびiFrame Playerが正常に表示できることを確認(※この作業で生成されるはず)
③次はTwitterにツィートする設定でコンテンツを保存

以上でTwitter CardsのPlayerカードの添付が利用できるはずですが、私の場合、何度申請しても「iPhoneで再生できない」らしく、承認してもらえていません。
過去にはPostカードの申請は承認してもらえていますので動画に関する箇所に問題があるのかと思っています。
現在、「twitter:player:stream」の指定を削除、および、iFrame PlayerにJW Playerを使用していたのをHTML5 Videoタグのみに修正して再度申請中です。
※JW Playerを使用するとPlayerにロゴが表示されるのとライセンスキーのチェックのためかjavascriptの許可を求められてしまうため、これも審査に引っかかるかもとやめました。

追記 2015.01.21
無事、申請が承認されました。
承認済み
 

Drupalバージョン

Drupal 7.x モジュール