Using ASP.NET to transform a query string parameter via a database

I wanted to have a database table of key/value pairs, and to create an ASP.NET page that would be passed the key in the URL query string and then needed to use the associated value in the JavaScript on that page.

First, the web.config that defines the connection string. It defines a datasource that connects to the host ‘db1.vc.example.com’ and a database on that host called ‘d1′. It also defines the username/password in the connection string, but integrated security may also work if the IIS worker can access the database.

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="database" connectionString="Data Source=db1.vc.example.com;Initial Catalog=d1;Integrated Security=False;User ID=user;Password=pass"/>
  </connectionStrings>
  <system.web>
    <customErrors mode="Off"/>
  </system.web>
</configuration>

And the aspx page that performs and uses the lookup. It uses SqlDataSource to define the Data Source, with the select parameter coming from the query string. Then there is a ListBox that uses the SqlDataSource as its own Data Source, executing the SQL query. Finally there is the JavaScript block that uses the <%= construct to get the value from the ListBox.

<%@ Page Language="C#" Debug="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title></title>
</head>
<body>
  <asp:SqlDataSource ID="database" runat="server" EnableCaching="true" ConnectionString="<%$ ConnectionStrings:database %>"
    Selectcommand="select [to] as target from mapping where [from] = @id">
    <selectparameters>
      <asp:QueryStringParameter Name="id" QueryStringField="id" />
    </selectparameters>
  </asp:SqlDataSource>
    
  <form id="form" runat="server" style="display: none">
    <asp:ListBox DataSourceId="database" ID="mapping" runat="server" DataTextField="target" DataValueField="target">
    </asp:ListBox>
  </form>
    
  <script type="text/javascript">
    alert("<%= (mapping.Items.Count > 0) ? mapping.Items[0].Value : "" %>");
  </script>
</body>
</html>

Encoding HLS video for JW Player 6

The newest JW Player supports reading HLS segmented content in a Flash player (which is very cool). However it didn’t work for me using HLS content created with Apple Compressor or FFmpeg + mediafilesegmenter. What did work was generating transport streams with FFmpeg and the m3u8-segmenter from https://github.com/johnf/m3u8-segmenter.

Generated multiple different bitrates using ffmpeg: (these are the Apple recommended HLS profiles) It’s possible to use named pipes to send the transport streams directly to m3u8-segmenter.

mkdir bbb.mpegts
ffmpeg -y -i bbb.mp4 -threads 0 -f mpegts \
  -acodec libfaac -ab 64k -ar 44100 -vcodec libx264 -vprofile baseline \
    -x264opts "fps=12:keyint=36:bitrate=200"  -s 416x234  bbb.mpegts/p1.ts \
  -acodec libfaac -ab 64k -ar 44100 -vcodec libx264 -vprofile baseline \
    -x264opts "fps=12:keyint=36:bitrate=400"  -s 480x270  bbb.mpegts/p2.ts \
  -acodec libfaac -ab 64k -ar 44100 -vcodec libx264 -vprofile baseline \
    -x264opts "fps=24:keyint=72:bitrate=600"  -s 640x360  bbb.mpegts/p3.ts \
  -acodec libfaac -ab 64k -ar 44100 -vcodec libx264 -vprofile baseline \
    -x264opts "fps=24:keyint=72:bitrate=1200" -s 640x360  bbb.mpegts/p4.ts \
  -acodec libfaac -ab 64k -ar 44100 -vcodec libx264 -vprofile main     \
    -x264opts "fps=24:keyint=72:bitrate=1800" -s 960x540  bbb.mpegts/p5.ts \
  -acodec libfaac -ab 64k -ar 44100 -vcodec libx264 -vprofile main     \
    -x264opts "fps=24:keyint=72:bitrate=2500" -s 960x540  bbb.mpegts/p6.ts \
  -acodec libfaac -ab 64k -ar 44100 -vcodec libx264 -vprofile main     \
    -x264opts "fps=24:keyint=72:bitrate=4500" -s 1280x720 bbb.mpegts/p7.ts

Created segments at six-second intervals, to fit the keyframes generated by ffmpeg:

mkdir bbb.hls
for p in p1 p2 p3 p4 p5 p6 p7; do mkdir bbb.hls/$p.seg; (cd bbb.hls; m3u8-segmenter --input ../bbb.mpegts/$p.ts --duration 6 --output-prefix $p.seg/$p --m3u8-file $p.m3u8 --url-prefix ""); done

Wrote a variant playlist that links all the profiles in ‘bbb.hls’:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=264000,RESOLUTION=416x234
p1.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=464000,RESOLUTION=480x270
p2.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=664000,RESOLUTION=640x360
p3.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1264000,RESOLUTION=640x360
p4.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1864000,RESOLUTION=960x540
p5.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2564000,RESOLUTION=960x540
p6.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=4564000,RESOLUTION=1280x720
p7.m3u8

The mpegts files can then be deleted, and the on-disk layout should look like this: (probably with many more TS files)

./p1.m3u8
./p1.seg
./p1.seg/p1-1.ts
./p1.seg/p1-2.ts
./p1.seg/p1-3.ts
./p2.m3u8
./p2.seg
./p2.seg/p2-1.ts
./p2.seg/p2-2.ts
./p2.seg/p2-3.ts
./p3.m3u8
./p3.seg
./p3.seg/p3-1.ts
./p3.seg/p3-2.ts
./p3.seg/p3-3.ts
./p4.m3u8
./p4.seg
./p4.seg/p4-1.ts
./p4.seg/p4-2.ts
./p4.seg/p4-3.ts
./p5.m3u8
./p5.seg
./p5.seg/p5-1.ts
./p5.seg/p5-2.ts
./p5.seg/p5-3.ts
./p6.m3u8
./p6.seg
./p6.seg/p6-1.ts
./p6.seg/p6-2.ts
./p6.seg/p6-3.ts
./p7.m3u8
./p7.seg
./p7.seg/p7-1.ts
./p7.seg/p7-2.ts
./p7.seg/p7-3.ts
./playlist.m3u8

If all these files are exposed via an HTTP server, you can pass playlist.m3u8 as the source to JW Player and it should work.

How to install Boot Camp on a 3TB Fusion Drive Mac

Warning: Following this process verbatim will wipe all data off your Mac. Do a Time Machine backup before starting.
Update: Using ‘Internet Recovery’ will normally fix anything that goes wrong with this process and will return your Mac to factory default
Update: Various people asked about variants on this process, for example when you have a 3TB HDD but no SSD – check the comments for the responses

This howto is for people who receive the Boot Camp Assistant error “Boot Camp does not support installing Windows on this Mac.” – “Boot Camp does not currently support installing Windows on a Mac with a 3 TB hard drive.”

The problem with installing Boot Camp on a 3TB Mac is due to the way the Boot Camp Assistant works, and the way the Mac EFI boots up Windows. The BCA normally makes some space at the end of the “disk” (either Fusion or normal) by shrinking the HFS+ partition, and then creates a FAT32 partition at the end you can install Windows into. The problem is that when the EFI boots up a Windows operating system it exposes an MBR-style partition to Windows by mapping the GUID partitions into the MBR space. The two issues with this are first that the FAT32 partition at the end would be in the 5th position (and MBR only supports four partitions) and second that the FAT32 partition ends beyond the 2TB boundary, which is also not possible with MBR.

My solution was to delete all the existing partitions, repartition the 3TB drive so that the FAT32 one is at position 3 (so that’s good for the MBR) and starts and ends within the 2TB limit, and then to recreate the Fusion Drive using the rest of the disk.

Here is the process:

Ideally, create a Mountain Lion 10.8.2 USB install drive (http://osxdaily.com/2012/02/17/make-bootable-os-x-10-8-mountain-lion-usb-install-drive/)
However for some reason I wasn’t able to get this to boot, kept getting that ‘no entry’ symbol. So actually I used the ‘OS X Recovery Disk Assistant’ (http://support.apple.com/kb/DL1433) in the end and installed the Mac OS over the Internet.

Create a Windows 8 USB install drive (http://www.microsoftstore.com/store/msstore/html/pbPage.Help_Win7_usbdvd_dwnTool) Note that if you have a problem booting from the stick with a BOOT/BCD error make sure you completely reinitialized the stick using Disk Utility’s “Erase” function to create a single FAT32 partition, then try the Win7 USB/DVD tool again.

Get Apple’s boot camp drivers (http://www.cafe-encounter.net/p682/download-bootcamp-drivers), extract and copy to the Windows USB stick

Plug MacOS install/recovery stick into iMac. Reboot iMac, hold down Cmd-R to boot from the Recovery USB drive
Open Terminal from the Utilities menu.

To delete the existing fusion drive, find the Logical Volume Group and Logical Volume GUIDs

-bash-3.2# diskutil coreStorage list
CoreStorage logical volume groups (1 found)
+-- Logical Volume Group 80387D15-BBD1-4DC9-9DF3-585CFA84E8E9
    =========================================================
    +-< Physical Volume 68C6107F-BEFD-4227-8791-AA52DB3D239E
    |   ----------------------------------------------------
    +-< Physical Volume 9C805962-1088-45E6-B036-4D5E5FF273CA
    |   ----------------------------------------------------
    +-> Logical Volume Family FE6CD53B-0664-4135-906D-56EC2BB745EC
        ----------------------------------------------------------
        +-> Logical Volume 9B2981DC-980A-43F1-80DF-89DF6052A339
            ---------------------------------------------------

Using the info above (simplified here), delete the Logical Volume:

-bash-3.2# diskutil coreStorage deleteVolume 9B2981DC-980A-43F1-80DF-89DF6052A339
Started CoreStorage operation on disk3 Macintosh HD
Unmounting disk3
Removing Logical Volume from Logical Volume Group
Finished CoreStorage operation on disk3 Macintosh HD

and the Logical Volume Group:

-bash-3.2# diskutil coreStorage delete 80387D15-BBD1-4DC9-9DF3-585CFA84E8E9
Started CoreStorage operation
Destroying Logical Volume Group
Erasing disk0s2
Initialized /dev/rdisk0s2 as a 113 GB HFS Plus volume with a 16384k journal
Mounting disk
Erasing disk1s2
Initialized /dev/rdisk1s2 as a 3 TB HFS Plus volume with a 229376k journal
Mounting disk
Finished CoreStorage operation

To repartition for 512GB Boot Camp: (partition list does not include recovery hd, the installer will create this for us)

-bash-3.2# diskutil partitionDisk disk1 2 GPTFormat fat32 BOOTCAMP 512G jhfs+ coreStorage R
Started partitioning on disk1
Unmounting disk
Creating the partition map
Waiting for the disks to reappear
Formatting disk1s2 as MS-DOS (FAT32) with name BOOTCAMP
4096 bytes per physical sector
/dev/rdisk1s2: 999755328 sectors in 15621177 FAT32 clusters (32768 bytes/cluster)
bps=512 spc=64 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=411648 drv=0x80 bsec=999999488 bspf=122048 rdcl=2 infs=1 bkbs=6
Mounting disk
Formatting disk1s3 as Mac OS Extended (Journaled) with name coreStorage
Initialized /dev/rdisk1s3 as a 2 TB HFS Plus volume with a 196608k journal
Mounting disk
Finished partitioning on disk1
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *3.0 TB     disk1
   1:                        EFI                         209.7 MB   disk1s1
   2:       Microsoft Basic Data BOOTCAMP                512.0 GB   disk1s2
   3:                  Apple_HFS coreStorage             2.5 TB     disk1s3

Recreate the Volume Group:

-bash-3.2# diskutil coreStorage create "Fusion Drive" disk0 disk1s3
Started CoreStorage operation
Unmounting disk0
Repartitioning disk0
Unmounting disk
Creating the partition map
Rediscovering disk0
Adding disk0s2 to Logical Volume Group
Unmounting disk1s3
Touching partition type on disk1s3
Adding disk1s3 to Logical Volume Group
Creating Core Storage Logical Volume Group
Switching disk0s2 to Core Storage
Switching disk1s3 to Core Storage
Waiting for Logical Volume Group to appear
Discovered new Logical Volume Group "2E019D11-B34D-4332-B176-249CE449CB29"
Core Storage LVG UUID: 2E019D11-B34D-4332-B176-249CE449CB29
Finished CoreStorage operation

Recreate the Logical Volume using the GUID displayed from the previous command:

-bash-3.2# diskutil coreStorage createVolume 2E019D11-B34D-4332-B176-249CE449CB29 jhfs+ "Macintosh HD" 100%
Started CoreStorage operation
Waiting for Logical Volume to appear
Formatting file system for Logical Volume
Initialized /dev/rdisk3 as a 2 TB HFS Plus volume with a 204800k journal
Mounting disk
Core Storage LV UUID: 209B3BC4-AE74-4258-9ED0-BA16D06DFC62
Core Storage disk: disk3
Finished CoreStorage operation

Exit Terminal, choose to Reinstall OS X, install on Macintosh HD.

After install completed and verified, replace the Mac OS install USB stick with the Windows one, reboot, hold Alt whilst booting and select ‘Windows’. (These are Windows 8 instructions, but 7 is similar)

Click ‘Next’ on the first screen asking you about localization settings, and on the next screen choose “Repair your computer” (if you proceed straight to Setup, it’ll claim your partition isn’t suitable for installation).

Open a Command Prompt either by selecting “Troubleshoot” and then “Advanced Options” and then “Command Prompt”, or by doing Shift-Function-F10.

X:\Sources>diskpart

Microsoft DiskPart version 6.2.9200

Copyright (C) 1999-2012 Microsoft Corporation.
On computer: MININT-H3JEAN1

DISKPART> list volume

  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  ----------  ---  -----------  -----  ----------  -------  ---------  --------
  Volume 0     D   BOOTCAMP     FAT32  Partition    476 GB  Healthy
  Volume 1         EFI          FAT32  Partition    200 MB  Healthy    Hidden
  Volume 2     C                NTFS   Removable     14 GB  Healthy

We want to switch around C and D, then format C and make it ‘Active’.

DISKPART> select volume 2

Volume 2 is the selected volume.

DISKPART> assign letter=e

DiskPart successfully assigned the drive letter or mount point.

DISKPART> select volume 0

Volume 0 is the selected volume.

DISKPART> assign letter=c

DiskPart successfully assigned the drive letter or mount point.

DISKPART> format fs=ntfs label="BOOTCAMP" quick

  100 percent completed

DiskPart successfully formatted the volume.

DISKPART> active

DiskPart marked the current partition as active.

At this point exit out, reboot, and go back into the installer. Now setup will let you install Windows on the “BOOTCAMP” partition.
After Setup completes you can install the Boot Camp drivers pack from the USB stick.

That’s it. You can boot into Windows by holding ‘Alt’ on startup, just like normal.