Introduction

I own an infomercial TV company and I do a a lot of P.I. or Per Inquiry ads on TV. Per Inquiry is where you pay a TV station 50% of what your ad sells instead of buying the TV time. My company places TV direct response ads on over 600 NBC, ABC, CBS, and FOX stations and 10 National Cable Networks on a Per Inquiry basis. Most of the successful Direct Response TV commercials you see on TV are being aired on a Per Inquiry basis. Even the best direct response TV ads would NOT make a penny if you bought the spot time. This is very different from "pay per click" because in the case of TV you only pay for actual orders received which means that you are guaranteed a profit on every order.

You can deal directly with the TV stations and put your TV ads on television at no cost. On the NBC, ABC, CBS, and FOX broadcast TV stations p.I. ads, if they work, pull from 5 to 25 orders a day and on national cable you get about 200 orders a day. So if you put your TV ad on 300 stations with an average of 10 orders a day per station or could generate about 21,000 orders a week without spending a penny on TV time. You don't need any ad agency to help you.
The sample project is a script editor and telepromoter that helps you create 30-second and 60-second TV spots. The main feature is the fact that it will time out the audio script for you so you don't have to keep reading it over and over with a stop watch.

Background

My favorite color for editing software of any kind is black so I made the GUI for the sample all black. I decided to pull components from various articles here on CodeProject so let me give credit here to those authors. I used code from the following projects here on CodeProject with some modifications:

The RichTextBox editor control uses the extended version of the RichTextBox (RTB) control from Microsoft or ExtendedRichTextBox.RichTextBoxPrintCtrl.

The speech component for reading and timing the length of each audio segment uses Microsoft's SpeechSynthesizer component.

SpeechSynthesizer

I tried writing an algorithm that would estimate the time to read a block of text but was unhappy with the results I kept getting so I decided to use Microsoft's Speech Synthesizer to actually read the text to get the reading time. If any readers have an algorithm that works, please let me know. The main purpose of the sample project with this article is to time how long it takes to read a piece of ad copy. It gets tedious very quickly reading text with a stopwatch and doing it over and over again every time you made a change to the ad copy which you are constantly doing in writing a TV commercial. The control for reading text in the RTF editor is shown below:

The Total Button calculates a running total of the read times in the "Time" column of the DataGridView. When you press the "Read Sel" button it will read the selected text in the RTF Editor / Teleprompter at the top of the screen. And if you right-mouse click on a Row Header in the bottom of the screen, you will get the context menu popup shown below that will read the text in the Audio column of the DatagridView at the bottom of the screen.

I should have written a wrapper class that implements IDisposable but I was lazy so it is important to understand that before and after reading a block of text, you must dispose of the object and reset the events used in the timing as follows:

 speaker.Dispose();
 speaker = new SpeechSynthesizer();
 speaker.SpeakStarted += new EventHandler<speakstartedeventargs>(speaker_SpeakStarted);
 speaker.SpeakCompleted +=
	new EventHandler<speakcompletedeventargs>(speaker_SpeakCompleted);
 speaker.SpeakProgress +=
	new EventHandler<speakprogresseventargs>(speaker_SpeakProgress);
</speakprogresseventargs></speakcompletedeventargs></speakstartedeventargs>

And on the firing of the SpeakCompleted event, you must also dispose the object as well as when closing the form. You can work with the RTF Editor / Telepromoter or the DataGridView or both for writing and timing your scripts. I prefer the DataGridView because it allows me to make easy notes about the video cover shots I will use with each audio take and I can drag and drop the edit lines around in the DataGridView easy to re-order the Audio text. I used the Amazing ProgressBar Control by Graham Wilson and the SpeakProgress event for the progress bar as follows:

private void speaker_SpeakProgress(object sender, SpeakProgressEventArgs e) {
     if (tbarProgressBar.Maximum - tbarProgressBar.Value > e.Text.Length)
	tbarProgressBar.Value =
            tbarProgressBar.Value + e.Text.Length;
     else
        tbarProgressBar.Value =
           tbarProgressBar.Maximum;
}

Painting An Ellipsis On The Splitterpanel

To help with the overall Black GUI look of the screen, I decided to make the SplitterPanel all black and to paint a white Ellipsis on the splitter bar so users could easily move the splitter bar up or down as shown below:

To accomplish this, I added some basic painting code as follows:

private void splitContainer1_Paint(object sender, PaintEventArgs e) {
     var control = sender as SplitContainer;
     Point[] points = new Point[3];
     var pointRect = Rectangle.Empty;
     var w = control.Width;
     var h = control.Height;
     var d = control.SplitterDistance;
     var sW = control.SplitterWidth;
     if (control.Orientation == Orientation.Horizontal) {
          points[0] = new Point((w / 2), d + (sW / 2));
          points[1] = new Point(points[0].X -10, points[0].Y);
          points[2] = new Point(points[0].X + 10, points[0].Y);
          pointRect = new Rectangle(points[1].X - 2, points[1].Y - 2, 25, 5);
     } else {
          points[0] = new Point(d + (sW / 2), (h / 2));
          points[1] = new Point(points[0].X, points[0].Y - 10);
          points[2] = new Point(points[0].X, points[0].Y + 10);
          pointRect = new Rectangle(points[1].X - 2, points[1].Y - 2, 5, 25);
     }
     foreach (Point p in points) { p.Offset(-2, -2);
          e.Graphics.FillEllipse(SystemBrushes.ControlDark,
		new Rectangle(p, new Size(10,10)));
          p.Offset(0, -3);
          e.Graphics.FillEllipse(SystemBrushes.ControlLight,
		new Rectangle(p, new Size(10,10)));
     }
}

Painting Vertical Text in Column Headers

To cool in keeping with my black motive, I thought I would creative an option for creating vertical text in the column headers as shown below:

To accomplish this is pretty simple and the code is as follows:

private void dgvVideoScript_CellPainting
	(object sender, DataGridViewCellPaintingEventArgs e) {
     ...
     if(cbVertical.Checked && (e.RowIndex == -1 && e.ColumnIndex >= 0))
     {
          e.PaintBackground(e.ClipBounds, true);
          Rectangle rect = this.dgvVideoScript.GetColumnDisplayRectangle
			(e.ColumnIndex, true);
          Size titleSize =
		TextRenderer.MeasureText(e.Value.ToString(), e.CellStyle.Font);
          if
            (this.dgvVideoScript.ColumnHeadersHeight < titleSize.Width)
            this.dgvVideoScript.ColumnHeadersHeight = titleSize.Width;
            e.Graphics.TranslateTransform(0, titleSize.Width);
            e.Graphics.RotateTransform(-90.0F); e.Graphics.DrawString(e.Value.ToString(),
            this.Font, Brushes.DarkRed, new PointF(rect.Y, rect.X));
            e.Graphics.RotateTransform(90.0F);
	   e.Graphics.TranslateTransform(0, -titleSize.Width);
            e.Handled = true;
          }
     }
}

Painting Row Count in Upper Left of DataGridView

I decided to paint the row count in the left most header cell and to add a listview to re-order the columns or turn on or off columns on a right mouse click in this cell as well as shown below:

The code for painting the row count in this cell is shown below:

private void dgvVideoScript_CellPainting(object sender,
	DataGridViewCellPaintingEventArgs e) {
     if (e.RowIndex == -1 && e.ColumnIndex == -1) {
          e.Graphics.FillRectangle(Brushes.Black, e.CellBounds);
          e.PaintContent(e.CellBounds);
          int z = dgvVideoScript.Rows.Count-1;
          e.Graphics.DrawString(z.ToString(),this.Font,
		Brushes.White, new PointF(e.CellBounds.Y + 2, e.CellBounds.X + 2));
          e.Handled = true;
     }
     ...
}

KeyBoard Commands

I included a number of common keyboard commands for the Telepromter as follows:

  • Esc / B - Stops scrolling and exits to main window
  • R - Restarts your script from the start
  • Spacebar - Pauses and unpauses the scrolling
  • F - Scrolls the text slightly faster
  • Y - Scrolls the text much faster
  • S - Scrolls the text slightly slower
  • T - Scrolls the text much slower
  • U - If text is scrolling down, it reverses the direction and scrolls up
  • D - If text is scrolling up, it reverses the direction and scrolls down

Fonts & Mirrors

In a typical teleprompter, you would include the ability to display text that can be read in a mirror so I included the free mirror True-Type Font called "KCAB" that displays text in reverse as you would see it in a mirror. There is a checkbox on the screen that will dynamically load and un-load this font as shown below:

private void cbMirrorFont_CheckedChanged(object sender, EventArgs e) {
     PrivateFontCollection myFonts;
     if (cbMirrorFont.Checked) {
          string fontPath = Application.StartupPath +
		"<a href="file://kcab.ttf">\\kcab.ttf</a>";
          if (File.Exists(fontPath)) {
            FontFamily family = LoadFontFamily(fontPath, out myFonts);
               theFont = new Font(family, 11.0f); this.CellTextBox.Font = theFont;
          }
     }
     else
          this.CellTextBox.Font = fontPrevious;
}

My Alien Logo

I had created my alien logo for another one of my software programs many years ago that I thought I would add to this project on the left of the two toolstrips. You can see this logo below:

In Conclusion

Every home video camera sold today is broadcast quality and there is a lot of free editing software available so anybody can create a 30-second or 60-second TV commercial to sell products literally without spending a penny. In addition, they can air that TV commercial they create on NBC, ABC, CBS, and FOX TV stations on a P.I. or Per Inquiry basis and pay nothing for the TV time. Instead they just pay 50% of what their TV commercial sells to the stations. So whether you have a kitchen gadget or a software application to sell TV is a great way to market your product or service. The final format for sending your TV commercial to a TV station is Betacam SP tape. Why? Because every TV station in the country accepts Betacam SP so after you finish your TV commercial, you will need to output it to a Betacam SP Tape recorder. I recommend buying a SONY Betacam SP UVW-1800 Deck and you can buy these decks with 50 hours or less on all the heads for $200 or less on ebay. And for those people who would like to do P.I. with TV stations, there is one caveat I must give you which is that the stations don't want to work with people who are to the business so when you call a station, NEVER, repeat NEVER ask a station if they will do P.I. because that tells them you know nothing about the business and they will work with you. Always ask a station for their avails and firesales and NEVER ask "how much" for any TV time. After asking for the avails and firesales, TELL THEM--do NOT ask--tell them you have direct response spots with high "Total Allowables" to air on P.I. and don't them they are your spots even if they are--they are your clients spots even if you are the client--but don't tell the station that you are the client and that the spot is selling your product! The Total Allowable is the amount the client offers in dollars to pay on each phone call--not on each order received and there are no adjustments for returns. Typically the Total Allowable is 50% or 60% of the sale price and the ad agency will split that with the station.

I created the Editor and Teleprompter here to make it easier for me to write my own TV ads and I hope you will also find it useful. Good luck!

Bill SerGioSerGio
www.GeminiGroupTV.com
www.StationBreak.net

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"